// 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)

// 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')
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 

var mss MSS = 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

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 _2ln_lb [] Vimbal = array.new<_2ln_lb>() 

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

var ob [] bullish_ob = array.new<ob>()
var ob [] bearish_ob = array.new<ob>()

var bx_ln [] bl_NWOG = array.new<bx_ln>()
var bx_ln [] bl_NDOG = array.new<bx_ln>()

var bx_ln_lb[] a_bx_ln_lb = array.new<bx_ln_lb>()

var FVG [] bFVG_UP = array.new<FVG>()
var FVG [] bFVG_DN = array.new<FVG>()

var FVG [] bBPR_UP = array.new<FVG>()
var FVG [] bBPR_DN = array.new<FVG>()

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))

var line _diag = line.new(na, na, na, na, color=color.new(color.silver, 50), style=line.style_dashed, xloc=xloc)
var line _vert = line.new(na, na, na, na, color=color.new(color.silver, 50), style=line.style_dotted, xloc=xloc)
var line _zero = line.new(na, na, na, na, color=color.new(color.silver, 5), style=line.style_solid , xloc=xloc, extend=ext)
var line _0236 = line.new(na, na, na, na, color=color.new(color.orange, 25), style=line.style_solid , xloc=xloc, extend=ext)
var line _0382 = line.new(na, na, na, na, color=color.new(color.yellow, 25), style=line.style_solid , xloc=xloc, extend=ext)
var line _0500 = line.new(na, na, na, na, color=color.new(color.green , 25), style=line.style_solid , xloc=xloc, extend=ext)
var line _0618 = line.new(na, na, na, na, color=color.new(color.yellow, 25), style=line.style_solid , xloc=xloc, extend=ext)
var line _0786 = line.new(na, na, na, na, color=color.new(color.orange, 25), style=line.style_solid , xloc=xloc, extend=ext)
var line _one_ = line.new(na, na, na, na, color=color.new(color.silver, 5), style=line.style_solid , xloc=xloc, extend=ext)
var line _1618 = line.new(na, na, na, na, color=color.new(color.yellow, 25), style=line.style_solid , xloc=xloc, extend=ext)

//-----------------------------------------------------------------------------
// 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 timeinrange(string res, string sess) => not na(time(timeframe.period, res, sess))

method setLine(line ln, int x1, float y1, int x2, float y2) => ln.set_xy1(x1, y1), ln.set_xy2(x2, y2)

method clear_aLine(line[] l) =>
    if l.size() > 0
        for i = l.size() -1 to 0
            l.pop().delete()

method clear_aLabLin(label[] l) =>
    if l.size() > 0
        for i = l.size() -1 to 0
            l.pop().delete()

method clear_aLabLin(line[] l) =>
    if l.size() > 0
        for i = l.size() -1 to 0
            l.pop().delete()

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

method display(ob id, css, break_css, str)=>
    if showOB
        if id.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)=>
    var os = 0
    var swing top = swing.new(na, na)
    var swing btm = swing.new(na, na)

    upper = ta.highest(len)
    lower = ta.lowest(len)

    os := high[len] > upper ? 0 : low[len] < lower ? 1 : os

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

    if os == 1 and os[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)
    var int dir= na, var int x1= na, var float y1= na, var int x2= na, var float y2= na
    //
    sz = aZZ.d.size()
    x2 := bar_index -1
    ph = ta.pivothigh(hi, left, 1)
    pl = ta.pivotlow(lo, left, 1)
    if ph   
        dir := aZZ.d.get(0)
        x1  := aZZ.x.get(0)
        y1  := aZZ.y.get(0)
        y2  := nz(hi[1])
        //
        if dir <  1  // if previous point was a pl, add, and change direction ( 1)
            aZZ.in_out(1, x1, y1, x2, y2, col, true)
        else
            if dir ==  1 and ph > y1 
                aZZ.x.set(0, x2), aZZ.y.set(0, y2)
        //
        // Liquidity
        if showLq and per and sz > 0
            count = 0
            st_P  = 0.
            st_B  = 0
            minP  = 0.
            maxP  = 10e6
            for i = 0 to math.min(sz, 50) -1
                if aZZ.d.get(i) ==  1 
                    if aZZ.y.get(i) > ph + (atr/a)
                        break
                    else
                        if aZZ.y.get(i) > ph - (atr/a) and aZZ.y.get(i) < ph + (atr/a)
                            count += 1
                            st_B := aZZ.x.get(i)
                            st_P := aZZ.y.get(i)
                            if aZZ.y.get(i) > minP
                                minP := aZZ.y.get(i)
                            if aZZ.y.get(i) < maxP 
                                maxP := aZZ.y.get(i)
            if count > 2
                getB = b_liq_B.get(0)
                if st_B == getB.bx.get_left()
                    getB.bx.set_top(math.avg(minP, maxP) + (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))
                      )
                     )      
                if b_liq_B.size() > visLiq
                    getLast = b_liq_B.pop()
                    getLast.bx.delete()
                    getLast.ln.delete()               
    //
    if pl
        dir := aZZ.d.get(0)
        x1  := aZZ.x.get(0)
        y1  := aZZ.y.get(0)
        y2  := nz(lo[1])
        //
        if dir > -1  // if previous point was a ph, add, and change direction (-1)
            aZZ.in_out(-1, x1, y1, x2, y2, col, true)
        else
            if dir == -1 and pl < y1 
                aZZ.x.set(0, x2), aZZ.y.set(0, y2)
        //
        // Liquidity
        if showLq and per and sz > 0
            count = 0
            st_P  = 0.
            st_B  = 0
            minP  = 0.
            maxP  = 10e6
            for i = 0 to math.min(sz, 50) -1
                if aZZ.d.get(i) == -1 
                    if aZZ.y.get(i) < pl - (atr/a)
                        break
                    else
                        if aZZ.y.get(i) > pl - (atr/a) and aZZ.y.get(i) < pl + (atr/a)
                            count += 1
                            st_B := aZZ.x.get(i)
                            st_P := aZZ.y.get(i)
                            if aZZ.y.get(i) > minP
                                minP := aZZ.y.get(i)
                            if aZZ.y.get(i) < maxP 
                                maxP := aZZ.y.get(i)
            if count > 2
                getB = b_liq_S.get(0)
                if st_B == getB.bx.get_left()
                    getB.bx.set_top(math.avg(minP, maxP) + (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))
                      )
                     )  
                if b_liq_S.size() > visLiq
                    getLast = b_liq_S.pop()
                    getLast.bx.delete()
                    getLast.ln.delete()            
    //
    // Market Structure Shift 
    if showMS 
        //
        iH = aZZ.d.get(2) ==  1 ? 2 : 1
        iL = aZZ.d.get(2) == -1 ? 2 : 1
        //
        switch
            // MSS Bullish
            close > aZZ.y.get(iH) and aZZ.d.get(iH) ==  1 and MSS.dir <  1 =>
                MSS.dir :=  1 
                if i_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) and aZZ.d.get(iL) == -1 and MSS.dir > -1 =>
                MSS.dir := -1 
                if i_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 ==  1 and close > aZZ.y.get(iH) and iBOS =>
                if MSS.l_bosBl.size() > 0
                    if aZZ.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  
                    if 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'))
            // BOS Bearish
            MSS.dir == -1 and close < aZZ.y.get(iL) and iBOS =>
                if MSS.l_bosBr.size() > 0
                    if aZZ.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
                    if 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'))
        if not iMSS
            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))

//-----------------------------------------------------------------------------
// Signal Generation for Buy and Sell
//-----------------------------------------------------------------------------

buySignal = close > open and close > high[1] // Buy signal condition
sellSignal = close < open and close < low[1] // Sell signal condition

plotshape(buySignal, style=shape.labelup, location=location.belowbar, color=color.green, text="BUY")
plotshape(sellSignal, style=shape.labeldown, location=location.abovebar, color=color.red, text="SELL")

//-----------------------------------------------------------------------------
// Calculations
//-----------------------------------------------------------------------------
if MSS.l_bosBl.size() > 200
    MSS.l_bosBl.pop().delete()
    MSS.lbBosBl.pop().delete()

if MSS.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') 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

// Pivot Points 
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

bsNOTbodyUP = ta.barssince(not L_bodyUP)
bsNOTbodyDN = ta.barssince(not L_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] 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()

// Fair Value Gap  
if barstate.isfirst
    for i = 0 to visBxs -1
        bFVG_UP.unshift(FVG.new(box(na), false))
        bFVG_DN.unshift(FVG.new(box(na), false))
        if i_BPR
            bBPR_UP.unshift(FVG.new(box(na), false))
            bBPR_DN.unshift(FVG.new(box(na), false))

if imbalanceUP and per and shwFVG 
    if imbalanceUP[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()

if imbalanceDN and per and shwFVG 
    if imbalanceDN[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)
if i_BPR and bFVG_UP.size() > 0 and bFVG_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())
    //
    if bxUPbtm < bxDNtop and 
       bxDNbtm < bxUPbtm
        if left == bBPR_UP.get(0).box.get_left() 
            if bBPR_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()
    //
    if bxDNbtm < bxUPtop and 
       bxUPbtm < bxDNbtm 
        if left == bBPR_DN.get(0).box.get_left() 
            if bBPR_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
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

for i = 0 to math.min(bxBack, bFVG_DN.size() -1)
    getDNi = bFVG_DN.get(i)
    if getDNi.active
        getDNi.box.set_right(bar_index +8)
        if high > getDNi.box.get_bottom() and not i_BPR
            getDNi.box.set_border_style(line.style_dashed)
        if high > getDNi.box.get_top()
            if not i_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

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
            
    for i = 0 to math.min(bxBack, bBPR_DN.size() -1)
        getDNi = bBPR_DN.get(i)
        if getDNi.active
            getDNi.box.set_right(bar_index +8)
            switch getDNi.pos 
                -1 =>
                    if high > getDNi.box.get_bottom()
                        getDNi.box.set_border_style(line.style_dashed)
                    if high > 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 =>
                    if low < getDNi.box.get_top()
                        getDNi.box.set_border_style(line.style_dashed)
                    if low < 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 
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)

if showOB and per
    if close > top.y and not top.crossed 
        top.crossed := true

        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)

if showOB and per
    if close < btm.y and not btm.crossed 
        btm.crossed := true

        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)

//-----------------------------------------------------------------------------
// Signal Generation for Buy and Sell
//-----------------------------------------------------------------------------

// Define buy and sell signals
buySignal = close > open and close > high[1] // Buy signal condition
sellSignal = close < open and close < low[1] // Sell signal condition

// Plot buy and sell signals
plotshape(buySignal, style=shape.labelup, location=location.belowbar, color=color.green, text="BUY")
plotshape(sellSignal, style=shape.labeldown, location=location.abovebar, color=color.red, text="SELL")

//-----------------------------------------------------------------------------
// End of the script
//-----------------------------------------------------------------------------


al siguiente codigo no quiero que me le modifique nada solo quiero que me le agregue una nueva funcion para que me envie als señales, me reajusta el codigo y me lo envia completo con la nueva funcion