ict code indicator
ict code indicator
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 = '····'
//---------------------------------------------------------------------------------
------------------------------------}
//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
// 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))
//---------------------------------------------------------------------------------
------------------------------------}
//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
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)
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
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]
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 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
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 orderBlocksSize > 0
maxOrderBlocks = internal ?
internalOrderBlocksSizeInput : swingOrderBlocksSizeInput
array<orderBlock> parsedOrdeBlocks = orderBlocks.slice(0,
math.min(maxOrderBlocks,orderBlocksSize))
array<box> b_oxes = internal ? internalOrderBlocksBoxes :
swingOrderBlocksBoxes
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)
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
if displayCondition
drawStructure(p_ivot,tag,bullishColor,lineStyle,label.style_label_down,labelSize)
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
if displayCondition
drawStructure(p_ivot,tag,bearishColor,lineStyle,label.style_label_up,labelSize)
// @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)
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)))
if not sameTimeframe
int leftIndex = times.binary_search_rightmost(parsedLeftTime)
int rightIndex =
times.binary_search_rightmost(parsedRightTime)
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))
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))
//---------------------------------------------------------------------------------
------------------------------------}
//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 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
drawLevels('D',timeframe.isdaily,dailyLevelsStyleInput,dailyLevelsColorInput)
drawLevels('W',timeframe.isweekly,weeklyLevelsStyleInput,weeklyLevelsColorInput)
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')
//@version=5
indicator("ICT Concepts [LuxAlgo]", max_lines_count=500, max_boxes_count=500,
max_labels_count=500, max_bars_back=3000, overlay=true)
//-----------------------------------------------------------------------------}
//Strings
//-----------------------------------------------------------------------------{
o = 'Options'
sp1 = ' '
sp2 = ' '
hl = 'High / Low ' + sp1
ny_ = 'New York' + sp1
lo_ = 'London Open'
lc_ = 'London Close'
as_ = 'Asian'
//-----------------------------------------------------------------------------}
//Settings
//-----------------------------------------------------------------------------{
i_mode = input.string( 'Present' , title = 'Mode'
, options =['Present', 'Historical'] )
//Displacement
sDispl = input.bool ( false , title = 'Show Displacement'
, group = 'Displacement' )
//Order Blocks
showOB = input.bool ( true , title = 'Show Order Blocks'
, group = 'Order Blocks' )
length = input.int ( 10 , title = 'Swing Lookback'
, group = 'Order Blocks' , minval = 3 )
showBull = input.int ( 1 , title = 'Show Last Bullish OB'
, group = 'Order Blocks' , minval = 0 )
showBear = input.int ( 1 , title = 'Show Last Bearish OB'
, group = 'Order Blocks' , minval = 0 )
useBody = input.bool ( true , title = 'Use Candle Body'
)
//OB Style
bullCss = input.color (color.new(#3e89fa, 0), title = 'Bullish
OB ' , group = 'Order Blocks' , inline = 'bullcss'
)
bullBrkCss = input.color (color.new(#4785f9, 85), title = 'Bullish
Break ' , group = 'Order Blocks' , inline = 'bullcss'
)
//Liquidity
showLq = input.bool ( true , title = 'Show Liquidity'
, group = 'Liquidity' )
a = 10 / input.float ( 4 , title = 'margin'
, group = 'Liquidity' , step = 0.1, minval = 2, maxval = 7 )
visLiq = input.int ( 2 , title = '# Visible Liq. boxes'
, group = 'Liquidity'
, minval = 1 , maxval = 50
, tooltip = 'In the same direction' )
cLIQ_B = input.color (color.new(#fa451c, 0), title = 'Buyside
Liquidity ' , group = 'Liquidity'
)
cLIQ_S = input.color (color.new(#1ce4fa, 0), title = 'Sellside
Liquidity' , group = 'Liquidity'
)
//FVG
shwFVG = input.bool ( true , title = 'Show FVGs'
, group = 'Fair Value Gaps' )
i_BPR = input.bool ( false , title = 'Balance Price Range'
, group = 'Fair Value Gaps' )
i_FVG = input.string( 'FVG' , title = o
, group = 'Fair Value Gaps' , options=['FVG', 'IFVG']
,
tooltip = 'Fair Value Gaps\nor\nImplied Fair Value Gaps' )
visBxs = input.int ( 2 , title = '# Visible FVG\'s'
, group = 'Fair Value Gaps'
, minval = 1 , maxval = 20
, tooltip = 'In the same direction' )
//FVG Style
cFVGbl = input.color (color.new(#00e676, 0), title = 'Bullish
FVG ' , group = 'Fair Value Gaps' , inline = 'FVGbl'
)
cFVGblBR = input.color (color.new(#808000, 0), title =
'Break' , group = 'Fair Value Gaps' , inline = 'FVGbl'
)
cFVGbr = input.color (color.new(#ff5252, 0), title = 'Bearish
FVG ' , group = 'Fair Value Gaps' , inline = 'FVGbr'
)
cFVGbrBR = input.color (color.new(#FF0000, 0), title =
'Break' , group = 'Fair Value Gaps' , inline = 'FVGbr'
)
//NWOG/NDOG
iNWOG = input.bool ( true , title = '' ,
inline='NWOG', group = 'NWOG/NDOG'
)
cNWOG1 = input.color (color.new(#ff5252, 28), title = 'NWOG ',
inline='NWOG', group = 'NWOG/NDOG'
)
cNWOG2 = input.color (color.new(#b2b5be, 50), title = '' ,
inline='NWOG', group = 'NWOG/NDOG'
)
maxNWOG = input.int ( 3 , title = 'Show max',
inline='NWOG', group = 'NWOG/NDOG' , minval = 0, maxval = 50
)
//Fibonacci
iFib = input.string( 'NONE' , title = 'Fibonacci between last:
', group = 'Fibonacci', options=['FVG', 'BPR', 'OB', 'Liq', 'VI', 'NWOG',
'NONE'])
iExt = input.bool ( false , title = 'Extend lines'
, group = 'Fibonacci' )
//Killzones
showKZ = input.bool ( false , title = 'Show Killzones'
, group = 'Killzones' )
//New York
showNy = input.bool ( true , title = ny_ , inline =
'ny' , group = 'Killzones'
) and showKZ
nyCss = input.color (color.new(#ff5d00, 93), title = '' , inline =
'ny' , group = 'Killzones'
)
//London Open
showLdno = input.bool ( true , title = lo_ , inline =
'lo' , group = 'Killzones'
) and showKZ
ldnoCss = input.color (color.new(#00bcd4, 93), title = '' , inline =
'lo' , group = 'Killzones'
)
//London Close
showLdnc = input.bool ( true , title = lc_ , inline =
'lc' , group = 'Killzones'
) and showKZ
ldncCss = input.color (color.new(#2157f3, 93), title = '' , inline =
'lc' , group = 'Killzones'
)
//Asian
showAsia = input.bool ( true , title = as_ + sp2, inline =
'as' , group = 'Killzones'
) and showKZ
asiaCss = input.color (color.new(#e91e63, 93), title = '' , inline =
'as' , group = 'Killzones'
)
//-----------------------------------------------------------------------------}
//General Calculations
//-----------------------------------------------------------------------------{
n = bar_index
hi = high
lo = low
tf_msec = timeframe.in_seconds(timeframe.period) * 1000
maxSize = 50
atr = ta.atr(10)
per = i_mode == 'Present' ? last_bar_index - bar_index <= 500 : true
perB = last_bar_index - bar_index <= 1000 ? true : false
xloc = iFib == 'OB' ? xloc.bar_time : xloc.bar_index
ext = iExt ? extend.right : extend.none
plus = iFib == 'OB' ? tf_msec * 50 : 50
mx = math.max(close , open)
mn = math.min(close , open)
body = math.abs(close - open)
meanBody = ta.sma (body , len)
max = useBody ? mx : high
min = useBody ? mn : low
blBrkConf = 0
brBrkConf = 0
r = color.r(chart.bg_color)
g = color.g(chart.bg_color)
b = color.b(chart.bg_color)
isDark = r < 80 and g < 80 and b < 80
//-----------------------------------------------------------------------------}
//User Defined Types
//-----------------------------------------------------------------------------{
type ZZ
int [] d
int [] x
float [] y
bool [] b
type ln_d
line l
int d
type _2ln_lb
line l1
line l2
label lb
type bx_ln
box b
line l
type bx_ln_lb
box bx
line ln
label lb
type mss
int dir
line [] l_mssBl
line [] l_mssBr
line [] l_bosBl
line [] l_bosBr
label[] lbMssBl
label[] lbMssBr
label[] lbBosBl
label[] lbBosBr
type liq
box bx
bool broken
bool brokenTop
bool brokenBtm
line ln
type ob
float top = na
float btm = na
int loc = bar_index
bool breaker = false
int break_loc = na
type swing
float y = na
int x = na
bool crossed = false
type FVG
box box
bool active
int pos
//-----------------------------------------------------------------------------}
//Variables
//-----------------------------------------------------------------------------{
maxVimb = 2
var float friCp = na, var int friCi = na // Friday Close price/index
var float monOp = na, var int monOi = na // Monday Open price/index
var float prDCp = na, var int prDCi = na // Previous Day Open price/index
var float cuDOp = na, var int cuDOi = na // Current Day Open price/index
var ZZ aZZ =
ZZ.new(
array.new < int >(maxSize, 0),
array.new < int >(maxSize, 0),
array.new < float >(maxSize, na),
array.new < bool >(maxSize, na))
//-----------------------------------------------------------------------------}
//Functions/methods
//-----------------------------------------------------------------------------{
method in_out(ZZ aZZ, int d, int x1, float y1, int x2, float y2, color col, bool b)
=>
aZZ.d.unshift(d), aZZ.x.unshift(x2), aZZ.y.unshift(y2), aZZ.b.unshift(b),
aZZ.d.pop(), aZZ.x.pop(), aZZ.y.pop(), aZZ.b.pop()
method setLine(line ln, int x1, float y1, int x2, float y2) => ln.set_xy1(x1, y1),
ln.set_xy2(x2, y2)
swings(len)=>
var os = 0
var swing top = swing.new(na, na)
var swing btm = swing.new(na, na)
upper = ta.highest(len)
lower = ta.lowest(len)
if os == 0 and os[1] != 0
top := swing.new(high[length], bar_index[length])
if os == 1 and os[1] != 1
btm := swing.new(low[length], bar_index[length])
[top, btm]
//-----------------------------------------------------------------------------}
//Calculations
//-----------------------------------------------------------------------------{
draw(len, color.yellow)
//Killzones
ny = time(timeframe.period, input.session('0700-0900', '', inline = 'ny',
group = 'Killzones'), 'America/New_York') and showNy
ldn_open = time(timeframe.period, input.session('0700-1000', '', inline = 'lo',
group = 'Killzones'), 'Europe/London' ) and showLdno // 0200-0500 UTC-5
ldn_close = time(timeframe.period, input.session('1500-1700', '', inline = 'lc',
group = 'Killzones'), 'Europe/London' ) and showLdnc // 1000-1200 UTC-5
asian = time(timeframe.period, input.session('1000-1400', '', inline = 'as',
group = 'Killzones'), 'Asia/Tokyo' ) and showAsia // 2000-0000 UTC-5
//Pivotpoints
ph = ta.pivothigh(3, 1), lPh = fixnan(ph)
pl = ta.pivotlow (3, 1), lPl = fixnan(pl)
//Candles
L_body =
high - mx < body * perc_Body and
mn - low < body * perc_Body
L_bodyUP = body > meanBody and L_body and close > open
L_bodyDN = body > meanBody and L_body and close < open
//Imbalance
imbalanceUP = L_bodyUP[1] and (i_FVG == 'FVG' ? low > high[2] : low < high[2])
imbalanceDN = L_bodyDN[1] and (i_FVG == 'FVG' ? high < low [2] : high > low [2])
//Volume Imbalance
vImb_Bl = open > close[1] and high[1] > low and close > close[1] and open >
open[1] and high[1] < mn
vImb_Br = open < close[1] and low [1] < high and close < close[1] and open <
open[1] and low [1] > mx
if sVimbl
if vImb_Bl
Vimbal.unshift(
_2ln_lb.new(
line.new (n -1, mx[1], n +3, mx[1], color=cVimbl)
, line.new (n , mn , n +3, mn , color=cVimbl)
, label.new(n +3, math.avg (mx[1], mn), text='VI'
, color=color(na) , textcolor=cVimbl, style=label.style_label_left)
)
)
if vImb_Br
Vimbal.unshift(
_2ln_lb.new(
line.new (n -1, mn[1], n +3, mn[1], color=cVimbl)
, line.new (n , mx , n +3, mx , color=cVimbl)
, label.new(n +3, math.avg (mn[1], mx), text='VI'
, color=color(na) , textcolor=cVimbl, style=label.style_label_left)
)
)
if Vimbal.size() > visVim
pop = Vimbal.pop()
pop.l1.delete()
pop.l2.delete()
pop.lb.delete()
//FVG's breaks
for i = 0 to math.min(bxBack, bFVG_UP.size() -1)
getUPi = bFVG_UP.get(i)
if getUPi.active
getUPi.box.set_right(bar_index +8)
if low < getUPi.box.get_top() and not i_BPR
getUPi.box.set_border_style(line.style_dashed)
if low < getUPi.box.get_bottom()
if not i_BPR
getUPi.box.set_bgcolor(color.new(cFVGblBR, 95))
getUPi.box.set_border_style(line.style_dotted)
getUPi.box.set_right(bar_index)
getUPi.active := false
if i_BPR
for i = 0 to math.min(bxBack, bBPR_UP.size() -1)
getUPi = bBPR_UP.get(i)
if getUPi.active
getUPi.box.set_right(bar_index +8)
switch getUPi.pos
-1 =>
if high > getUPi.box.get_bottom()
getUPi.box.set_border_style(line.style_dashed)
if high > getUPi.box.get_top ()
getUPi.box.set_bgcolor(color.new(cFVGblBR, 95))
getUPi.box.set_border_style(line.style_dotted)
getUPi.box.set_right(bar_index)
getUPi.active := false
1 =>
if low < getUPi.box.get_top ()
getUPi.box.set_border_style(line.style_dashed)
if low < getUPi.box.get_bottom()
getUPi.box.set_bgcolor(color.new(cFVGblBR, 95))
getUPi.box.set_border_style(line.style_dotted)
getUPi.box.set_right(bar_index)
getUPi.active := false
//NWOG/NDOG
if barstate.isfirst
for i = 0 to maxNWOG -1
bl_NWOG.unshift(bx_ln.new(box(na), line(na)))
for i = 0 to maxNDOG -1
bl_NDOG.unshift(bx_ln.new(box(na), line(na)))
if dayofweek == dayofweek.friday
friCp := close, friCi := n
if ta.change(dayofweek)
if dayofweek == dayofweek.monday and iNWOG
monOp := open , monOi := n
bl_NWOG.unshift(bx_ln.new(
box.new(
friCi , math.max (friCp , monOp )
, monOi , math.min (friCp , monOp )
, bgcolor = color ( na )
, border_color = cNWOG2
, extend = extend.right )
,
line.new(
monOi , math.avg (friCp , monOp )
, monOi +1 , math.avg (friCp , monOp )
, color = cNWOG1
, style = line.style_dotted
, extend = extend.right )
))
bl = bl_NWOG.pop(), bl.b.delete(), bl.l.delete()
if iNDOG
cuDOp := open , cuDOi := n
prDCp := close[1], prDCi := n -1
//
bl_NDOG.unshift(bx_ln.new(
box.new(
prDCi , math.max (prDCp , cuDOp )
, cuDOi , math.min (prDCp , cuDOp )
, bgcolor = color ( na )
, border_color = cNDOG2
, extend = extend.right )
,
line.new(
cuDOi , math.avg (prDCp , cuDOp )
, cuDOi +1 , math.avg (prDCp , cuDOp )
, color = cNDOG1
, style = line.style_dotted
, extend = extend.right )
))
bl = bl_NDOG.pop(), bl.b.delete(), bl.l.delete()
//Liquidity
for i = 0 to b_liq_B.size() -1
x = b_liq_B.get(i)
if not x.broken
x.bx.set_right(n +3)
x.ln.set_x2 (n +3)
if not x.brokenTop
if close > x.bx.get_top ()
x.brokenTop := true
if not x.brokenBtm
if close > x.bx.get_bottom()
x.brokenBtm := true
if x.brokenBtm
x.bx.set_bgcolor(color.new(cLIQ_B, 90))
x.ln.delete()
if x.brokenTop
x.broken := true
x.bx.set_right(n)
for i = 0 to b_liq_S.size() -1
x = b_liq_S.get(i)
if not x.broken
x.bx.set_right(n +3)
x.ln.set_x2 (n +3)
if not x.brokenTop
if close < x.bx.get_top ()
x.brokenTop := true
if not x.brokenBtm
if close < x.bx.get_bottom()
x.brokenBtm := true
if x.brokenTop
x.bx.set_bgcolor(color.new(cLIQ_S, 90))
x.ln.delete()
if x.brokenBtm
x.broken := true
x.bx.set_right(n)
//Order Blocks
[top, btm] = swings(length)
minima = max[1]
maxima = min[1]
loc = time[1]
for i = 1 to (n - top.x)-1
minima := math.min(min[i], minima)
maxima := minima == min[i] ? max[i] : maxima
loc := minima == min[i] ? time[i] : loc
bullish_ob.unshift(ob.new(maxima, minima, loc))
if bullish_ob.size() > 0
for i = bullish_ob.size()-1 to 0
element = bullish_ob.get(i)
if not element.breaker
if math.min(close, open) < element.btm
element.breaker := true
element.break_loc := time
else
if close > element.top
bullish_ob.remove(i)
else if i < showBull and top.y < element.top and top.y >
element.btm
blBrkConf := 1
//Set label
if blBrkConf > blBrkConf[1] and showLabels
label.new(top.x, top.y, '▼', color = na
, textcolor = bearCss.notransp()
, style = label.style_label_down
, size = size.tiny)
minima = min[1]
maxima = max[1]
loc = time[1]
for i = 1 to (n - btm.x)-1
maxima := math.max(max[i], maxima)
minima := maxima == max[i] ? min[i] : minima
loc := maxima == max[i] ? time[i] : loc
bearish_ob.unshift(ob.new(maxima, minima, loc))
if bearish_ob.size() > 0
for i = bearish_ob.size()-1 to 0
element = bearish_ob.get(i)
if not element.breaker
if math.max(close, open) > element.top
element.breaker := true
element.break_loc := time
else
if close < element.btm
bearish_ob.remove(i)
else if i < showBear and btm.y > element.btm and btm.y <
element.top
brBrkConf := 1
//Set label
if brBrkConf > brBrkConf[1] and showLabels
label.new(btm.x, btm.y, '▲', color = na
, textcolor = bullCss.notransp()
, style = label.style_label_up
, size = size.tiny)
//-----------------------------------------------------------------------------}
//Set Order Blocks
//-----------------------------------------------------------------------------{
if barstate.islast and showOB
if a_bx_ln_lb.size() > 0
for i = a_bx_ln_lb.size() -1 to 0
item = a_bx_ln_lb.remove(i)
item.bx.delete()
item.ln.delete()
item.lb.delete()
//Bullish
if showBull > 0
blSz = bullish_ob.size()
if blSz > 0
for i = 0 to math.min(showBull, bullish_ob.size()) -1
get_ob = bullish_ob.get(i)
get_ob.display(bullCss, bullBrkCss, 'bl')
//Bearish
if showBear > 0
brSz = bearish_ob.size()
if brSz > 0
for i = 0 to math.min(showBear, bearish_ob.size()) -1
get_ob = bearish_ob.get(i)
get_ob.display(bearCss, bearBrkCss, 'br')
//-----------------------------------------------------------------------------}
//Fibonacci
//-----------------------------------------------------------------------------{
if barstate.islast
x1 = 0, y1 = 0., x2 = 0, y2 = 0., box up = na, box dn = na
switch iFib
'FVG' =>
if bFVG_UP.size() > 0 and bFVG_DN.size() > 0
up := bFVG_UP.get(0).box
dn := bFVG_DN.get(0).box
dnFirst = up.get_left() > dn.get_left()
dnBottm = up.get_top () > dn.get_top ()
x1 := dnFirst ? dn.get_left () : up.get_left ()
x2 := dnFirst ? up.get_right () : dn.get_right ()
y1 := dnFirst ?
dnBottm ? dn.get_bottom() : dn.get_top () :
dnBottm ? up.get_top () : up.get_bottom()
y2 := dnFirst ?
dnBottm ? up.get_top () : up.get_bottom() :
dnBottm ? dn.get_bottom() : dn.get_top ()
'BPR' =>
if bBPR_UP.size() > 0 and bBPR_DN.size() > 0
up := bBPR_UP.get(0).box
dn := bBPR_DN.get(0).box
dnFirst = up.get_left() > dn.get_left()
dnBottm = up.get_top () > dn.get_top ()
x1 := dnFirst ? dn.get_left () : up.get_left ()
x2 := dnFirst ? up.get_right () : dn.get_right ()
y1 := dnFirst ?
dnBottm ? dn.get_bottom() : dn.get_top () :
dnBottm ? up.get_top () : up.get_bottom()
y2 := dnFirst ?
dnBottm ? up.get_top () : up.get_bottom() :
dnBottm ? dn.get_bottom() : dn.get_top ()
'OB' =>
oSz = a_bx_ln_lb.size()
if oSz > 1
xA = nz(
a_bx_ln_lb.get(oSz -1).ln.get_x1 ()
, a_bx_ln_lb.get(oSz -1).bx.get_left ()
)
xB = nz(
a_bx_ln_lb.get(oSz -2).ln.get_x1 ()
, a_bx_ln_lb.get(oSz -2).bx.get_left ()
)
AFirst = xB > xA
//
yAT = nz(
a_bx_ln_lb.get(oSz -1).ln.get_y1 ()
, a_bx_ln_lb.get(oSz -1).bx.get_top ()
)
yAB = nz(
a_bx_ln_lb.get(oSz -1).ln.get_y1 ()
, a_bx_ln_lb.get(oSz -1).bx.get_bottom()
)
yBT = nz(
a_bx_ln_lb.get(oSz -2).ln.get_y1 ()
, a_bx_ln_lb.get(oSz -2).bx.get_top ()
)
yBB = nz(
a_bx_ln_lb.get(oSz -2).ln.get_y1 ()
, a_bx_ln_lb.get(oSz -2).bx.get_bottom()
)
ABottom = yAB < yBB
//
x1 := AFirst ? xA : xB
x2 := AFirst ? xB : xA
y1 := AFirst ?
ABottom ? yAB : yAT :
ABottom ? yBT : yBB
y2 := AFirst ?
ABottom ? yBT : yBB :
ABottom ? yAB : yAT
'Liq' =>
if b_liq_B.size() > 0 and b_liq_S.size() > 0
xA = nz(
b_liq_B.get(0).ln.get_x1 ()
, b_liq_B.get(0).bx.get_left ()
)
xB = nz(
b_liq_S.get(0).ln.get_x1 ()
, b_liq_S.get(0).bx.get_left ()
)
AFirst = xB > xA
//
yAT = nz(
b_liq_B.get(0).ln.get_y1 ()
, b_liq_B.get(0).bx.get_top ()
)
yAB = nz(
b_liq_B.get(0).ln.get_y1 ()
, b_liq_B.get(0).bx.get_bottom()
)
yBT = nz(
b_liq_S.get(0).ln.get_y1 ()
, b_liq_S.get(0).bx.get_top ()
)
yBB = nz(
b_liq_S.get(0).ln.get_y1 ()
, b_liq_S.get(0).bx.get_bottom()
)
ABottom = yAB < yBB
//
x1 := AFirst ? xA : xB
x2 := AFirst ? xB : xA
y1 := AFirst ?
ABottom ? yAB : yAT :
ABottom ? yBT : yBB
y2 := AFirst ?
ABottom ? yBT : yBB :
ABottom ? yAB : yAT
'VI' =>
if Vimbal.size() > 1
AxA = Vimbal.get(1).l2.get_x1(), AxB = Vimbal.get(1).l1.get_x1()
BxA = Vimbal.get(0).l2.get_x1(), BxB = Vimbal.get(0).l1.get_x1()
AyA = Vimbal.get(1).l2.get_y1(), AyB = Vimbal.get(1).l1.get_y1()
ByA = Vimbal.get(0).l2.get_y1(), ByB = Vimbal.get(0).l1.get_y1()
ABt = math.min(ByA, ByB) > math.min(AyA, AyB)
x1 := math.max(AxA, AxB)
x2 := math.max(BxA, BxB)
y1 := ABt ? math.min(AyA, AyB) : math.max(AyA, AyB)
y2 := ABt ? math.max(ByA, ByB) : math.min(ByA, ByB)
'NWOG' =>
if bl_NWOG.size() > 1
up := bl_NWOG.get(0).b
dn := bl_NWOG.get(1).b
dnFirst = up.get_left() > dn.get_left()
dnBottm = up.get_top () > dn.get_top ()
x1 := dnFirst ? dn.get_left () : up.get_left ()
x2 := dnFirst ? up.get_right() : dn.get_right()
y1 := dnFirst ?
dnBottm ? dn.get_bottom() : dn.get_top () :
dnBottm ? up.get_top () : up.get_bottom()
y2 := dnFirst ?
dnBottm ? up.get_top () : up.get_bottom() :
dnBottm ? dn.get_bottom() : dn.get_top ()
//
if iFib != 'NONE'
rt = math.max(x1, x2)
lt = math.min(x1, x2)
tp = math.max(y1, y2)
bt = math.min(y1, y2)
_0 = rt == x1 ? y1 : y2
_1 = rt == x1 ? y2 : y1
//
df = _1 - _0
m0236 = df * 0.236
m0382 = df * 0.382
m0500 = df * 0.500
m0618 = df * 0.618
m0786 = df * 0.786
m1618 = df * 1.618
//
_diag.setLine(x1, y1 , x2 , y2 )
_vert.setLine(rt, _0 , rt , _0 + m1618)
_zero.setLine(rt, _0 , rt + plus, _0 )
_0236.setLine(rt, _0 + m0236, rt + plus, _0 + m0236)
_0382.setLine(rt, _0 + m0382, rt + plus, _0 + m0382)
_0500.setLine(rt, _0 + m0500, rt + plus, _0 + m0500)
_0618.setLine(rt, _0 + m0618, rt + plus, _0 + m0618)
_0786.setLine(rt, _0 + m0786, rt + plus, _0 + m0786)
_one_.setLine(rt, _1 , rt + plus, _1 )
_1618.setLine(rt, _0 + m1618, rt + plus, _0 + m1618)
//-----------------------------------------------------------------------------}
//Displacement
//-----------------------------------------------------------------------------{
plotshape(sDispl ? per ?
L_bodyUP ? low : na : na : na
, title = 'Displacement UP'
, style = shape.labelup
, color = color.lime
, location = location.belowbar)
plotshape(sDispl ? per ?
L_bodyDN ? high : na : na : na
, title = 'Displacement DN'
, style = shape.labeldown
, color = color.red
, location = location.abovebar)
//-----------------------------------------------------------------------------}
//background - Killzones
//-----------------------------------------------------------------------------{
bgcolor (per ? ny ? nyCss : na : na, editable = false)
bgcolor (per ? ldn_open ? ldnoCss : na : na, editable = false)
bgcolor (per ? ldn_close ? ldncCss : na : na, editable = false)
bgcolor (per ? asian ? asiaCss : na : na, editable = false)
//-----------------------------------------------------------------------------}
//@version=5
indicator("Liquidity Swings [LuxAlgo]"
, overlay = true
, max_lines_count = 500
, max_labels_count = 500
, max_boxes_count = 500)
//------------------------------------------------------------------------------
//Settings
//-----------------------------------------------------------------------------{
length = input(14, 'Pivot Lookback')
//Style
showTop = input(true, 'Swing High' , inline = 'top', group =
'Style')
topCss = input(color.red, '' , inline = 'top', group =
'Style')
topAreaCss = input(color.new(color.red, 50), 'Area', inline = 'top', group =
'Style')
//-----------------------------------------------------------------------------}
//Functions
//-----------------------------------------------------------------------------{
n = bar_index
if condition
count := 0
vol := 0.
else
if intraPrecision
if n > length
if array.size(v[length]) > 0
for [index, element] in v[length]
vol += array.get(l[length], index) < top and
array.get(h[length], index) > btm ? element : 0
else
vol += low[length] < top and high[length] > btm ? volume[length] : 0
[count, vol]
if ta.crossover(target, filterValue)
lbl := label.new(x, y, str.tostring(vol, format.volume)
, style = lbl_style
, size = label_size
, color = #00000000
, textcolor = css)
if condition
if target[1] < filterValue[1]
line.delete(lvl[1])
else if not crossed[1]
line.set_x2(lvl, n - length)
if not crossed[1]
line.set_x2(lvl, n+3)
if ta.crossover(target, filterValue)
bx := box.new(x, top, x + count, btm
, border_color = na
, bgcolor = css)
//-----------------------------------------------------------------------------}
//Global variables
//-----------------------------------------------------------------------------{
//Pivot high
var float ph_top = na
var float ph_btm = na
var bool ph_crossed = na
var ph_x1 = 0
var box ph_bx = box.new(na,na,na,na
, bgcolor = color.new(topAreaCss, 80)
, border_color = na)
//Pivot low
var float pl_top = na
var float pl_btm = na
var bool pl_crossed = na
var pl_x1 = 0
var box pl_bx = box.new(na,na,na,na
, bgcolor = color.new(btmAreaCss, 80)
, border_color = na)
//-----------------------------------------------------------------------------}
//Display pivot high levels/blocks
//-----------------------------------------------------------------------------{
ph = ta.pivothigh(length, length)
//Get ph counts
[ph_count, ph_vol] = get_counts(ph, ph_top, ph_btm)
ph_x1 := n - length
ph_crossed := false
if ph_crossed
box.set_right(ph_bx, ph_x1)
else
box.set_right(ph_bx, n+3)
if showTop
//Set ph zone
set_zone(ph, ph_x1, ph_top, ph_btm, ph_count, ph_vol, topAreaCss)
//Set ph level
set_level(ph, ph_crossed, ph_top, ph_count, ph_vol, topCss)
//Set ph label
set_label(ph_count, ph_vol, ph_x1, ph_top, topCss, label.style_label_down)
//-----------------------------------------------------------------------------}
//Display pivot low levels/blocks
//-----------------------------------------------------------------------------{
pl = ta.pivotlow(length, length)
//Get pl counts
[pl_count, pl_vol] = get_counts(pl, pl_top, pl_btm)
pl_x1 := n - length
pl_crossed := false
if pl_crossed
box.set_right(pl_bx, pl_x1)
else
box.set_right(pl_bx, n+3)
if showBtm
//Set pl zone
set_zone(pl, pl_x1, pl_top, pl_btm, pl_count, pl_vol, btmAreaCss)
//Set pl level
set_level(pl, pl_crossed, pl_btm, pl_count, pl_vol, btmCss)
//Set pl labels
set_label(pl_count, pl_vol, pl_x1, pl_btm, btmCss, label.style_label_up)