Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
34 KiB
ICT Concepts
// 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("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'] )
//Market Structure Shift
showMS=input.bool ( true,title='',group='Market Structures',inline='MS' )
len=input.int ( 5,title=' Length '+sp2,group='Market Structures',inline='MS',minval=3,maxval=10 )
iMSS=input.bool ( true,title=' MSS'+sp1,group='Market Structures',inline='M1' )
cMSSbl=input.color (color.new(#00e6a1,0),title='bullish',group='Market Structures',inline='M1' )
cMSSbr=input.color (color.new(#e60400,0),title='bearish',group='Market Structures',inline='M1' )
iBOS=input.bool ( true,title=' BOS'+sp1,group='Market Structures',inline='BS' )
cBOSbl=input.color (color.new(#00e6a1,0),title='bullish',group='Market Structures',inline='BS' )
cBOSbr=input.color (color.new(#e60400,0),title='bearish',group='Market Structures',inline='BS' )
//Displacement
sDispl=input.bool ( false,title='Show Displacement',group='Displacement' )
perc_Body=0.36// input.int( 36, minval=1, maxval=36) / 100
bxBack=10// input.int( 10, minval=0, maxval=10)
sVimbl=input.bool ( true,title='',group='Volume Imbalance',inline='VI' )
visVim=input.int ( 2,title=" # Visible VI's "+sp1,group='Volume Imbalance',inline='VI',minval=2,maxval=100 )
cVimbl=input.color (color.new(#06b2d0,0),title='',group='Volume Imbalance',inline='VI' )
//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' )
bearCss=input.color (color.new(#FF3131,0),title='Bearish OB',group='Order Blocks',inline='bearcss' )
bearBrkCss=input.color (color.new(#f9ff57,85),title='Bearish Break',group='Order Blocks',inline='bearcss' )
showLabels=input.bool ( false,title='Show Historical Polarity Changes',group='Order Blocks' )
//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 )
iNDOG=input.bool ( false,title='',inline='NDOG',group='NWOG/NDOG' )
cNDOG1=input.color (color.new(#ff9800,20),title='NDOG ',inline='NDOG',group='NWOG/NDOG' )
cNDOG2=input.color (color.new(#4dd0e1,65),title='',inline='NDOG',group='NWOG/NDOG' )
maxNDOG=input.int ( 1,title='Show max',inline='NDOG',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' ) andshowKZ
nyCss=input.color (color.new(#ff5d00,93),title='',inline='ny',group='Killzones' )
//London Open
showLdno=input.bool ( true,title=lo_,inline='lo',group='Killzones' ) andshowKZ
ldnoCss=input.color (color.new(#00bcd4,93),title='',inline='lo',group='Killzones' )
//London Close
showLdnc=input.bool ( true,title=lc_,inline='lc',group='Killzones' ) andshowKZ
ldncCss=input.color (color.new(#2157f3,93),title='',inline='lc',group='Killzones' )
//Asian
showAsia=input.bool ( true,title=as_+sp2,inline='as',group='Killzones' ) andshowKZ
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<80andg<80andb<80
//-----------------------------------------------------------------------------}
//User Defined Types
//-----------------------------------------------------------------------------{
typeZZ
int [] d
int [] x
float [] y
bool [] b
typeln_d
linel
intd
type_2ln_lb
linel1
linel2
labellb
typebx_ln
boxb
linel
typebx_ln_lb
boxbx
lineln
labellb
typemss
intdir
line [] l_mssBl
line [] l_mssBr
line [] l_bosBl
line [] l_bosBr
label[] lbMssBl
label[] lbMssBr
label[] lbBosBl
label[] lbBosBr
typeliq
boxbx
boolbroken
boolbrokenTop
boolbrokenBtm
lineln
typeob
floattop=na
floatbtm=na
intloc=bar_index
boolbreaker=false
intbreak_loc=na
typeswing
floaty=na
intx=na
boolcrossed=false
typeFVG
boxbox
boolactive
intpos
varmssMSS=mss.new(
0
,array.new<line>()
,array.new<line>()
,array.new<line>()
,array.new<line>()
,array.new<label>()
,array.new<label>()
,array.new<label>()
,array.new<label>()
)
//-----------------------------------------------------------------------------}
//Variables
//-----------------------------------------------------------------------------{
maxVimb=2
varfloatfriCp=na,varintfriCi=na// Friday Close price/index
varfloatmonOp=na,varintmonOi=na// Monday Open price/index
varfloatprDCp=na,varintprDCi=na// Previous Day Open price/index
varfloatcuDOp=na,varintcuDOi=na// Current Day Open price/index
var_2ln_lb [] Vimbal=array.new< _2ln_lb>()
varliq [] b_liq_B=array.new< liq>(1,liq.new(box(na),false,false,false,line(na)))
varliq [] b_liq_S=array.new< liq>(1,liq.new(box(na),false,false,false,line(na)))
varob [] bullish_ob=array.new< ob>()
varob [] bearish_ob=array.new< ob>()
varbx_ln [] bl_NWOG=array.new< bx_ln>()
varbx_ln [] bl_NDOG=array.new< bx_ln>()
varbx_ln_lb[] a_bx_ln_lb=array.new< bx_ln_lb>()
varFVG [] bFVG_UP=array.new< FVG>()
varFVG [] bFVG_DN=array.new< FVG>()
varFVG [] bBPR_UP=array.new< FVG>()
varFVG [] bBPR_DN=array.new< FVG>()
varZZaZZ=
ZZ.new(
array.new<int>(maxSize,0),
array.new<int>(maxSize,0),
array.new<float>(maxSize,na),
array.new<bool>(maxSize,na))
varline_diag=line.new(na,na,na,na,color=color.new(color.silver,50),style=line.style_dashed,xloc=xloc )
varline_vert=line.new(na,na,na,na,color=color.new(color.silver,50),style=line.style_dotted,xloc=xloc )
varline_zero=line.new(na,na,na,na,color=color.new(color.silver,5),style=line.style_solid,xloc=xloc,extend=ext)
varline_0236=line.new(na,na,na,na,color=color.new(color.orange,25),style=line.style_solid,xloc=xloc,extend=ext)
varline_0382=line.new(na,na,na,na,color=color.new(color.yellow,25),style=line.style_solid,xloc=xloc,extend=ext)
varline_0500=line.new(na,na,na,na,color=color.new(color.green,25),style=line.style_solid,xloc=xloc,extend=ext)
varline_0618=line.new(na,na,na,na,color=color.new(color.yellow,25),style=line.style_solid,xloc=xloc,extend=ext)
varline_0786=line.new(na,na,na,na,color=color.new(color.orange,25),style=line.style_solid,xloc=xloc,extend=ext)
varline_one_=line.new(na,na,na,na,color=color.new(color.silver,5),style=line.style_solid,xloc=xloc,extend=ext)
varline_1618=line.new(na,na,na,na,color=color.new(color.yellow,25),style=line.style_solid,xloc=xloc,extend=ext)
//-----------------------------------------------------------------------------}
//Functions/methods
//-----------------------------------------------------------------------------{
methodin_out(ZZaZZ,intd,intx1,floaty1,intx2,floaty2,colorcol,boolb) =>
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()
methodtimeinrange(stringres,stringsess) =>notna(time(timeframe.period,res,sess))
methodsetLine(lineln,intx1,floaty1,intx2,floaty2) =>ln.set_xy1(x1,y1),ln.set_xy2(x2,y2)
methodclear_aLine(line[] l) =>
ifl.size() >0
fori=l.size() -1to0
l.pop().delete()
methodclear_aLabLin(label[] l) =>
ifl.size() >0
fori=l.size() -1to0
l.pop().delete()
methodclear_aLabLin(line[] l) =>
ifl.size() >0
fori=l.size() -1to0
l.pop().delete()
methodnotransp(colorcss) =>color.rgb(color.r(css),color.g(css),color.b(css))
methoddisplay(obid,css,break_css,str)=>
ifshowOB
ifid.breaker
a_bx_ln_lb.unshift(
bx_ln_lb.new(
box.new(id.loc,id.top,timenow+ (tf_msec*10),id.btm,na
,bgcolor=break_css
,extend=extend.none
,xloc=xloc.bar_time)
,line (na)
,label(na))
)
else
y=str=='bl'?id.btm:id.top
s=str=='bl'?label.style_label_up:label.style_label_down
a_bx_ln_lb.unshift(
bx_ln_lb.new(
box(na)
,line.new(id.loc,y,id.loc+ (tf_msec*10),y
,xloc=xloc.bar_time,color=css,width=2)
,label.new( id.loc+ (tf_msec*10),y
,text=str=='bl'?'+OB':'-OB'
,xloc=xloc.bar_time
,style=s,color=color(na)
,textcolor=css,size=size.small))
)
swings(len)=>
varos=0
varswingtop=swing.new(na,na)
varswingbtm=swing.new(na,na)
upper=ta.highest(len)
lower=ta.lowest(len)
os:=high[len] >upper?0
:low [len] <lower?1:os
ifos==0andos[1] !=0
top:=swing.new(high[length],bar_index[length])
ifos==1andos[1] !=1
btm:=swing.new(low[length],bar_index[length])
[top,btm]
set_lab(i,str) =>
style=str=='Bl'?label.style_label_down:label.style_label_up
txcol=str=='Bl'?color.lime:color.red
label.new(math.round(math.avg(aZZ.x.get(i),n)),aZZ.y.get(i),text='BOS'
,style=style,color=color(na),textcolor=txcol,size=size.tiny)
set_lin(i,str) =>
color=str=='Bl'?color.lime:color.red
line.new(aZZ.x.get(i),aZZ.y.get(i),n,aZZ.y.get(i),color=color,style=line.style_dotted)
draw(left,col) =>
//
max_bars_back(time,1000)
varintdir=na,varintx1=na,varfloaty1=na,varintx2=na,varfloaty2=na
//
sz=aZZ.d.size( )
x2:=bar_index-1
ph=ta.pivothigh(hi,left,1)
pl=ta.pivotlow (lo,left,1)
ifph
dir:=aZZ.d.get (0)
x1:=aZZ.x.get (0)
y1:=aZZ.y.get (0)
y2:=nz(hi[1])
//
ifdir<1// if previous point was a pl, add, and change direction ( 1)
aZZ.in_out( 1,x1,y1,x2,y2,col,true)
else
ifdir==1andph>y1
aZZ.x.set(0,x2),aZZ.y.set(0,y2)
//
// liquidity
ifshowLqandperandsz>0
count=0
st_P=0.
st_B=0
minP=0.
maxP=10e6
fori=0tomath.min(sz,50) -1
ifaZZ.d.get(i) ==1
ifaZZ.y.get(i) >ph+ (atr/a)
break
else
ifaZZ.y.get(i) >ph- (atr/a) andaZZ.y.get(i) <ph+ (atr/a)
count+=1
st_B:=aZZ.x.get(i)
st_P:=aZZ.y.get(i)
ifaZZ.y.get(i) >minP
minP:=aZZ.y.get(i)
ifaZZ.y.get(i) <maxP
maxP:=aZZ.y.get(i)
ifcount>2
getB=b_liq_B.get(0)
ifst_B==getB.bx.get_left()
getB.bx.set_top(math.avg(minP,maxP) + (atr/a))
getB.bx.set_rightbottom(n+10,math.avg(minP,maxP) - (atr/a))
else
b_liq_B.unshift(liq.new(
box.new(
st_B,math.avg(minP,maxP) + (atr/a),n+10,math.avg(minP,maxP) - (atr/a)
,text='Buyside liquidity',text_size=size.tiny,text_halign=text.align_left
,text_valign=text.align_bottom,text_color=color.new(cLIQ_B,25)
,bgcolor=color(na),border_color=color(na)
)
,false
,false
,false
,line.new(st_B,st_P,n-1,st_P,color=color.new(cLIQ_B,0))
)
)
ifb_liq_B.size() >visLiq
getLast=b_liq_B.pop()
getLast.bx.delete()
getLast.ln.delete()
//
ifpl
dir:=aZZ.d.get (0)
x1:=aZZ.x.get (0)
y1:=aZZ.y.get (0)
y2:=nz(lo[1])
//
ifdir>-1// if previous point was a ph, add, and change direction (-1)
aZZ.in_out(-1,x1,y1,x2,y2,col,true)
else
ifdir==-1andpl<y1
aZZ.x.set(0,x2),aZZ.y.set(0,y2)
//
//Liquidity
ifshowLqandperandsz>0
count=0
st_P=0.
st_B=0
minP=0.
maxP=10e6
fori=0tomath.min(sz,50) -1
ifaZZ.d.get(i) ==-1
ifaZZ.y.get(i) <pl- (atr/a)
break
else
ifaZZ.y.get(i) >pl- (atr/a) andaZZ.y.get(i) <pl+ (atr/a)
count+=1
st_B:=aZZ.x.get(i)
st_P:=aZZ.y.get(i)
ifaZZ.y.get(i) >minP
minP:=aZZ.y.get(i)
ifaZZ.y.get(i) <maxP
maxP:=aZZ.y.get(i)
ifcount>2
getB=b_liq_S.get(0)
ifst_B==getB.bx.get_left()
getB.bx.set_top(math.avg(minP,maxP) + (atr/a))
getB.bx.set_rightbottom(n+10,math.avg(minP,maxP) - (atr/a))
else
b_liq_S.unshift(liq.new(
box.new(
st_B,math.avg(minP,maxP) + (atr/a),n+10,math.avg(minP,maxP) - (atr/a)
,text='Sellside liquidity',text_size=size.tiny,text_halign=text.align_left
,text_valign=text.align_bottom,text_color=color.new(cLIQ_S,25)
,bgcolor=color(na),border_color=color(na)
)
,false
,false
,false
,line.new(st_B,st_P,n-1,st_P,color=color.new(cLIQ_S,0))
)
)
ifb_liq_S.size() >visLiq
getLast=b_liq_S.pop()
getLast.bx.delete()
getLast.ln.delete()
//
//Market Structure Shift
ifshowMS
//
iH=aZZ.d.get(2) ==1?2:1
iL=aZZ.d.get(2) ==-1?2:1
//
switch
// MSS Bullish
close>aZZ.y.get(iH) andaZZ.d.get(iH) ==1andMSS.dir<1=>
MSS.dir:=1
ifi_mode=='Present'
MSS.l_bosBl.clear_aLabLin(),MSS.l_bosBr.clear_aLabLin()
MSS.lbBosBl.clear_aLabLin(),MSS.lbBosBr.clear_aLabLin()
MSS.l_mssBl.clear_aLabLin(),MSS.l_mssBr.clear_aLabLin()
MSS.lbMssBl.clear_aLabLin(),MSS.lbMssBr.clear_aLabLin()
//
MSS.l_mssBl.unshift(line.new (
aZZ.x.get(iH),aZZ.y.get(iH),n,aZZ.y.get(iH),color=cMSSbl))
MSS.lbMssBl.unshift(label.new(
math.round(math.avg(aZZ.x.get(iH),n)),aZZ.y.get(iH),text='MSS'
,style=label.style_label_down,size=size.tiny,color=color(na),textcolor=cMSSbl))
// MSS Bearish
close<aZZ.y.get(iL) andaZZ.d.get(iL) ==-1andMSS.dir>-1=>
MSS.dir:=-1
ifi_mode=='Present'
MSS.l_bosBl.clear_aLabLin(),MSS.l_bosBr.clear_aLabLin()
MSS.lbBosBl.clear_aLabLin(),MSS.lbBosBr.clear_aLabLin()
MSS.l_mssBl.clear_aLabLin(),MSS.l_mssBr.clear_aLabLin()
MSS.lbMssBl.clear_aLabLin(),MSS.lbMssBr.clear_aLabLin()
//
MSS.l_mssBr.unshift(line.new (
aZZ.x.get(iL),aZZ.y.get(iL),n,aZZ.y.get(iL),color=cMSSbr))
MSS.lbMssBr.unshift(label.new(
math.round(math.avg(aZZ.x.get(iL),n)),aZZ.y.get(iL),text='MSS'
,style=label.style_label_up,size=size.tiny,color=color(na),textcolor=cMSSbr))
// BOS Bullish
MSS.dir==1andclose>aZZ.y.get(iH) andiBOS=>
ifMSS.l_bosBl.size() >0
ifaZZ.y.get(iH) !=MSS.l_bosBl.get(0).get_y2() and
aZZ.y.get(iH) !=MSS.l_mssBl.get(0).get_y2()
MSS.l_bosBl.unshift(set_lin(iH,'Bl')),MSS.lbBosBl.unshift(set_lab(iH,'Bl'))
else
ifaZZ.y.get(iH) !=MSS.l_mssBl.get(0).get_y2()
MSS.l_bosBl.unshift(set_lin(iH,'Bl')),MSS.lbBosBl.unshift(set_lab(iH,'Bl'))
// BOS Bearish
MSS.dir==-1andclose<aZZ.y.get(iL) andiBOS=>
ifMSS.l_bosBr.size() >0
ifaZZ.y.get(iL) !=MSS.l_bosBr.get(0).get_y2() and
aZZ.y.get(iL) !=MSS.l_mssBr.get(0).get_y2()
MSS.l_bosBr.unshift(set_lin(iL,'Br')),MSS.lbBosBr.unshift(set_lab(iL,'Br'))
else
ifaZZ.y.get(iL) !=MSS.l_mssBr.get(0).get_y2()
MSS.l_bosBr.unshift(set_lin(iL,'Br')),MSS.lbBosBr.unshift(set_lab(iL,'Br'))
ifnotiMSS
MSS.l_mssBl.get(0).set_color(color(na)),MSS.lbMssBl.get(0).set_textcolor(color(na))
MSS.l_mssBr.get(0).set_color(color(na)),MSS.lbMssBr.get(0).set_textcolor(color(na))
//-----------------------------------------------------------------------------}
//Calculations
//-----------------------------------------------------------------------------{
draw(len,color.yellow)
ifMSS.l_bosBl.size() >200
MSS.l_bosBl.pop().delete()
MSS.lbBosBl.pop().delete()
ifMSS.l_bosBr.size() >200
MSS.l_bosBr.pop().delete()
MSS.lbBosBr.pop().delete()
//Killzones
ny=time(timeframe.period,input.session('0700-0900','',inline='ny',group='Killzones'),'America/New_York') andshowNy
ldn_open=time(timeframe.period,input.session('0700-1000','',inline='lo',group='Killzones'),'Europe/London' ) andshowLdno// 0200-0500 UTC-5
ldn_close=time(timeframe.period,input.session('1500-1700','',inline='lc',group='Killzones'),'Europe/London' ) andshowLdnc// 1000-1200 UTC-5
asian=time(timeframe.period,input.session('1000-1400','',inline='as',group='Killzones'),'Asia/Tokyo' ) andshowAsia// 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_Bodyand
mn-low<body*perc_Body
L_bodyUP=body>meanBodyandL_bodyandclose>open
L_bodyDN=body>meanBodyandL_bodyandclose<open
bsNOTbodyUP=ta.barssince(notL_bodyUP)
bsNOTbodyDN=ta.barssince(notL_bodyDN)
bsIs_bodyUP=ta.barssince( L_bodyUP)
bsIs_bodyDN=ta.barssince( L_bodyDN)
lwst=math.min(lPh [bsNOTbodyUP[1]],low[bsNOTbodyUP[1]])
hgst=math.max(high[bsNOTbodyDN[1]],lPl[bsNOTbodyDN[1]])
//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] andhigh[1] >lowandclose>close[1] andopen>open[1] andhigh[1] <mn
vImb_Br=open<close[1] andlow [1] <highandclose<close[1] andopen<open[1] andlow [1] >mx
ifsVimbl
ifvImb_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)
)
)
ifvImb_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)
)
)
ifVimbal.size() >visVim
pop=Vimbal.pop()
pop.l1.delete()
pop.l2.delete()
pop.lb.delete()
//Fair Value Gap
ifbarstate.isfirst
fori=0tovisBxs-1
bFVG_UP.unshift(FVG.new(box(na),false))
bFVG_DN.unshift(FVG.new(box(na),false))
ifi_BPR
bBPR_UP.unshift(FVG.new(box(na),false))
bBPR_DN.unshift(FVG.new(box(na),false))
ifimbalanceUPandperandshwFVG
ifimbalanceUP[1]
bFVG_UP.get(0).box.set_lefttop (n-2,low )
bFVG_UP.get(0).box.set_rightbottom(n+8,high[2])
else
bFVG_UP.unshift(FVG.new(
box.new(
n-2
,i_FVG=='FVG'?low:high[2]
,n,i_FVG=='FVG'?high[2] :low
,bgcolor=i_BPR?color(na) :color.new(cFVGbl,90)
,border_color=i_BPR?color(na) :color.new(cFVGbl,65)
,text_color=i_BPR?color(na) :color.new(cFVGbl,65)
,text_size=size.small
,text=i_FVG
)
,true)
)
bFVG_UP.pop().box.delete()
ifimbalanceDNandperandshwFVG
ifimbalanceDN[1]
bFVG_DN.get(0).box.set_lefttop (n-2,low[2])
bFVG_DN.get(0).box.set_rightbottom(n+8,high )
else
bFVG_DN.unshift(FVG.new(
box.new(
n-2
,i_FVG=='FVG'?low[2] :high
,n,i_FVG=='FVG'?high:low[2]
,bgcolor=i_BPR?color(na) :color.new(cFVGbr,90)
,border_color=i_BPR?color(na) :color.new(cFVGbr,65)
,text_color=i_BPR?color(na) :color.new(cFVGbr,65)
,text_size=size.small
,text=i_FVG
)
,true)
)
bFVG_DN.pop().box.delete()
//Balance Price Range (overlap of 2 latest FVG bull/bear)
ifi_BPRandbFVG_UP.size() >0andbFVG_DN.size() >0
bxUP=bFVG_UP.get(0)
bxDN=bFVG_DN.get(0)
bxUPbtm=bxUP.box.get_bottom()
bxDNbtm=bxDN.box.get_bottom()
bxUPtop=bxUP.box.get_top()
bxDNtop=bxDN.box.get_top()
left=math.min(bxUP.box.get_left (),bxDN.box.get_left ())
right=math.max(bxUP.box.get_right(),bxDN.box.get_right())
//
ifbxUPbtm<bxDNtopand
bxDNbtm<bxUPbtm
ifleft==bBPR_UP.get(0).box.get_left()
ifbBPR_UP.get(0).active
bBPR_UP.get(0).box.set_right(right)
else
bBPR_UP.unshift(FVG.new(
box.new(
left,bxDNtop,right,bxUPbtm
,bgcolor=i_BPR?color.new(cFVGbl,90) :color(na)
,border_color=i_BPR?color.new(cFVGbl,65) :color(na)
,text_color=i_BPR?color.new(cFVGbl,65) :color(na)
,text_size=size.small
,text='BPR'
)
,true
,close>bxUPbtm?1:close<bxDNtop?-1:0
)
)
bBPR_UP.pop().box.delete()
//
ifbxDNbtm<bxUPtopand
bxUPbtm<bxDNbtm
ifleft==bBPR_DN.get(0).box.get_left()
ifbBPR_DN.get(0).active
bBPR_DN.get(0).box.set_right(right)
else
bBPR_DN.unshift(FVG.new(
box.new(
left,bxUPtop,right,bxDNbtm
,bgcolor=i_BPR?color.new(cFVGbr,90) :color(na)
,border_color=i_BPR?color.new(cFVGbr,65) :color(na)
,text_color=i_BPR?color.new(cFVGbr,65) :color(na)
,text_size=size.small
,text='BPR'
)
,true
,close>bxDNbtm?1:close<bxUPtop?-1:0
)
)
bBPR_DN.pop().box.delete()
//FVG's breaks
fori=0tomath.min(bxBack,bFVG_UP.size() -1)
getUPi=bFVG_UP.get(i)
ifgetUPi.active
getUPi.box.set_right(bar_index+8)
iflow<getUPi.box.get_top() andnoti_BPR
getUPi.box.set_border_style(line.style_dashed)
iflow<getUPi.box.get_bottom()
ifnoti_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
fori=0tomath.min(bxBack,bFVG_DN.size() -1)
getDNi=bFVG_DN.get(i)
ifgetDNi.active
getDNi.box.set_right(bar_index+8)
ifhigh>getDNi.box.get_bottom() andnoti_BPR
getDNi.box.set_border_style(line.style_dashed)
ifhigh>getDNi.box.get_top()
ifnoti_BPR
getDNi.box.set_bgcolor(color.new(cFVGbrBR,95))
getDNi.box.set_border_style(line.style_dotted)
getDNi.box.set_right(bar_index)
getDNi.active:=false
ifi_BPR
fori=0tomath.min(bxBack,bBPR_UP.size() -1)
getUPi=bBPR_UP.get(i)
ifgetUPi.active
getUPi.box.set_right(bar_index+8)
switchgetUPi.pos
-1=>
ifhigh>getUPi.box.get_bottom()
getUPi.box.set_border_style(line.style_dashed)
ifhigh>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=>
iflow<getUPi.box.get_top ()
getUPi.box.set_border_style(line.style_dashed)
iflow<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
fori=0tomath.min(bxBack,bBPR_DN.size() -1)
getDNi=bBPR_DN.get(i)
ifgetDNi.active
getDNi.box.set_right(bar_index+8)
switchgetDNi.pos
-1=>
ifhigh>getDNi.box.get_bottom()
getDNi.box.set_border_style(line.style_dashed)
ifhigh>getDNi.box.get_top ()
getDNi.box.set_bgcolor(color.new(cFVGbrBR,95))
getDNi.box.set_border_style(line.style_dotted)
getDNi.box.set_right(bar_index)
getDNi.active:=false
1=>
iflow<getDNi.box.get_top ()
getDNi.box.set_border_style(line.style_dashed)
iflow<getDNi.box.get_bottom()
getDNi.box.set_bgcolor(color.new(cFVGbrBR,95))
getDNi.box.set_border_style(line.style_dotted)
getDNi.box.set_right(bar_index)
getDNi.active:=false
//NWOG/NDOG
ifbarstate.isfirst
fori=0tomaxNWOG-1
bl_NWOG.unshift(bx_ln.new(box(na),line(na)))
fori=0tomaxNDOG-1
bl_NDOG.unshift(bx_ln.new(box(na),line(na)))
ifdayofweek==dayofweek.friday
friCp:=close,friCi:=n
ifta.change(dayofweek)
ifdayofweek==dayofweek.mondayandiNWOG
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()
ifiNDOG
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
fori=0tob_liq_B.size() -1
x=b_liq_B.get(i)
ifnotx.broken
x.bx.set_right(n+3)
x.ln.set_x2 (n+3)
ifnotx.brokenTop
ifclose>x.bx.get_top ()
x.brokenTop:=true
ifnotx.brokenBtm
ifclose>x.bx.get_bottom()
x.brokenBtm:=true
ifx.brokenBtm
x.bx.set_bgcolor(color.new(cLIQ_B,90))
x.ln.delete()
ifx.brokenTop
x.broken:=true
x.bx.set_right(n)
fori=0tob_liq_S.size() -1
x=b_liq_S.get(i)
ifnotx.broken
x.bx.set_right(n+3)
x.ln.set_x2 (n+3)
ifnotx.brokenTop
ifclose<x.bx.get_top ()
x.brokenTop:=true
ifnotx.brokenBtm
ifclose<x.bx.get_bottom()
x.brokenBtm:=true
ifx.brokenTop
x.bx.set_bgcolor(color.new(cLIQ_S,90))
x.ln.delete()
ifx.brokenBtm
x.broken:=true
x.bx.set_right(n)
//Order Blocks
[top,btm] =swings(length)
ifshowOBandper
ifclose>top.yandnottop.crossed
top.crossed:=true
minima=max[1]
maxima=min[1]
loc=time[1]
fori=1to (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))
ifbullish_ob.size() >0
fori=bullish_ob.size()-1to0
element=bullish_ob.get(i)
ifnotelement.breaker
ifmath.min(close,open) <element.btm
element.breaker:=true
element.break_loc:=time
else
ifclose>element.top
bullish_ob.remove(i)
elseifi<showBullandtop.y<element.topandtop.y>element.btm
blBrkConf:=1
//Set label
ifblBrkConf>blBrkConf[1] andshowLabels
label.new(top.x,top.y,'▼',color=na
,textcolor=bearCss.notransp()
,style=label.style_label_down
,size=size.tiny)
ifshowOBandper
ifclose<btm.yandnotbtm.crossed
btm.crossed:=true
minima=min[1]
maxima=max[1]
loc=time[1]
fori=1to (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))
ifbearish_ob.size() >0
fori=bearish_ob.size()-1to0
element=bearish_ob.get(i)
ifnotelement.breaker
ifmath.max(close,open) >element.top
element.breaker:=true
element.break_loc:=time
else
ifclose<element.btm
bearish_ob.remove(i)
elseifi<showBearandbtm.y>element.btmandbtm.y<element.top
brBrkConf:=1
//Set label
ifbrBrkConf>brBrkConf[1] andshowLabels
label.new(btm.x,btm.y,'▲',color=na
,textcolor=bullCss.notransp()
,style=label.style_label_up
,size=size.tiny)
//-----------------------------------------------------------------------------}
//Set Order Blocks
//-----------------------------------------------------------------------------{
ifbarstate.islastandshowOB
ifa_bx_ln_lb.size() >0
fori=a_bx_ln_lb.size() -1to0
item=a_bx_ln_lb.remove(i)
item.bx.delete()
item.ln.delete()
item.lb.delete()
//Bullish
ifshowBull>0
blSz=bullish_ob.size()
ifblSz>0
fori=0tomath.min(showBull,bullish_ob.size()) -1
get_ob=bullish_ob.get(i)
get_ob.display(bullCss,bullBrkCss,'bl')
//Bearish
ifshowBear>0
brSz=bearish_ob.size()
ifbrSz>0
fori=0tomath.min(showBear,bearish_ob.size()) -1
get_ob=bearish_ob.get(i)
get_ob.display(bearCss,bearBrkCss,'br')
//-----------------------------------------------------------------------------}
//Fibonacci
//-----------------------------------------------------------------------------{
ifbarstate.islast
x1=0,y1=0.,x2=0,y2=0.,boxup=na,boxdn=na
switchiFib
'FVG'=>
ifbFVG_UP.size() >0andbFVG_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'=>
ifbBPR_UP.size() >0andbBPR_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()
ifoSz>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'=>
ifb_liq_B.size() >0andb_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'=>
ifVimbal.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'=>
ifbl_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 ()
//
ifiFib!='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)
//-----------------------------------------------------------------------------}