Indicator · Pine Script v6 · On the chart

TRINITY 2.0

by sam56100· code credited to SAMANYFX / © LuxAlgo

A smart money concepts overlay that marks market structure shifts and breaks of structure, order blocks, volume imbalances, buyside and sellside liquidity zones and fair value gaps, with an optional balance price range view.

View on GitHub

GitHub stars1on the repository
Pine versionv6current
Lines of code786
Settings40inputs
LicenceNone statedfile: MPL-2.0
Last update5 months ago5 May 2026

Add It to Your TradingView Chart

  1. 1Copy the scriptPress Copy script above, or the copy button on the code below.
  2. 2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
  3. 3Paste over the templateCreate a new indicator, select all of the template text and paste. Press Save and give it a name.
  4. 4Add it to the chartPress Add to chart, then adjust the settings with the gear icon next to its name.

Source Code

786 lines of Pine Script v6 from TRINITY.pine, published under MPL-2.0 (file header). Keep the author's credit and licence lines when you reuse it.

TRINITY.pine
// This Pine Script® code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © SAMANYFX / © LuxAlgo
//@version=6
indicator("TRINITY 2.0", overlay=true, max_lines_count=500, max_boxes_count=500, max_labels_count=500, max_bars_back=3000)
o          = 'Options'
sp1        = '       '
sp2        = '              '
ny_        = 'New York'       + sp1
lo_        = 'London Open'
lc_        = 'London Close'
as_        = 'Asian'
i_mode     = input.string('Present', title='Mode', options=['Present', 'Historical'])
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')
sDispl     = input.bool(false, title='Show Displacement', group='Displacement')
perc_Body  = 0.36
bxBack     = 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')
showOB     = input.bool(true,  title='Show Order Blocks',    group='Order Blocks')
ob_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(false, title='Use Candle Body')
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')
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)
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')
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'])
visBxs     = input.int (2,     title="# Visible FVG's",      group='Fair Value Gaps', minval=1, maxval=20)
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')
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)
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')
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')
showLdno   = input.bool(true,  title=lo_, inline='lo', group='Killzones') and showKZ
ldnoCss    = input.color(color.new(#00bcd4, 93), title='', inline='lo', group='Killzones')
showLdnc   = input.bool(true,  title=lc_, inline='lc', group='Killzones') and showKZ
ldncCss    = input.color(color.new(#2157f3, 93), title='', inline='lc', group='Killzones')
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')
g_ote      = "OTE Zone"
ote_fib1   = input.float(0.618, "Fib 0.618", group=g_ote, step=0.001)
ote_fib2   = input.float(0.786, "Fib 0.786", group=g_ote, step=0.001)
cOTEbull   = input.color(color.new(#00e676, 85), "OTE Long",  group=g_ote)
cOTEbear   = input.color(color.new(#ff5252, 85), "OTE Short", group=g_ote)
g_tri          = "TRINITY Setup"
tri_close      = input.bool(true, "Alertes sur cloture seulement", group=g_tri)
// tri_strictZone supprimé : le signal se déclenche sans attendre le prix dans l'OTE
//-----------------------------------------------------------------------------}
// GENERAL
//-----------------------------------------------------------------------------{
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
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
//-----------------------------------------------------------------------------}
// TYPES
//-----------------------------------------------------------------------------{
type ZZ
    int   [] d
    int   [] x
    float [] y
    bool  [] b
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
//-----------------------------------------------------------------------------{
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, false))
var float friCp = na, var int friCi = na
var float monOp = na, var int monOi = na
var float prDCp = na, var int prDCi = na
var float cuDOp = na, var int cuDOi = 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)
// OTE variables
var float tl_obBtm   = na
var float tl_obTop   = na
var int   tl_obLoc   = na
var float tl_swingHi = na
var bool  tl_mssOk   = false
var box   tl_oteBox  = na
var float ts_obBtm   = na
var float ts_obTop   = na
var int   ts_obLoc   = na
var float ts_swingLo = na
var bool  ts_mssOk   = false
var box   ts_oteBox  = na
var float ote_buy_lo = na
var float ote_buy_hi = na
var float ote_sel_lo = na
var float ote_sel_hi = na
var int   prevMSSdir = 0
var int   tl_ob_bar  = 0   // bar_index quand le TL OB a été détecté
var int   ts_ob_bar  = 0   // bar_index quand le TS OB a été détecté
//-----------------------------------------------------------------------------}
// METHODS
//-----------------------------------------------------------------------------{
method in_out(ZZ aZZ, int d, int x2, float y2) =>
    aZZ.d.unshift(d), aZZ.x.unshift(x2), aZZ.y.unshift(y2), aZZ.b.unshift(false), 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)
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)))
// FIX #1 : swings() utilise le paramètre correctement
swings(swingLen) =>
    var os = 0
    var swing top = swing.new(na, na)
    var swing btm = swing.new(na, na)
    upper = ta.highest(swingLen)
    lower = ta.lowest(swingLen)
    os := high[swingLen] > upper ? 0 : low[swingLen] < lower ? 1 : os
    if os == 0 and os[1] != 0
        top := swing.new(high[swingLen], bar_index[swingLen])
    if os == 1 and os[1] != 1
        btm := swing.new(low[swingLen], bar_index[swingLen])
    [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) =>
    col = str == 'Bl' ? color.lime : color.red
    line.new(aZZ.x.get(i), aZZ.y.get(i), n, aZZ.y.get(i), color=col, style=line.style_dotted)
// FIX #2 : MSS/BOS logic extraite dans une fonction dédiée
detect_mss() =>
    if showMS
        iH = aZZ.d.get(2) == 1 ? 2 : 1
        iL = aZZ.d.get(2) == -1 ? 2 : 1
        switch
            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))
            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))
            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'))
            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))
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 not na(ph)
        dir := aZZ.d.get(0), x1 := aZZ.x.get(0), y1 := aZZ.y.get(0), y2 := nz(hi[1])
        if dir < 1
            aZZ.in_out(1, x2, y2)
        else
            if dir == 1 and ph > y1
                aZZ.x.set(0, x2), aZZ.y.set(0, y2)
        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 not na(pl)
        dir := aZZ.d.get(0), x1 := aZZ.x.get(0), y1 := aZZ.y.get(0), y2 := nz(lo[1])
        if dir > -1
            aZZ.in_out(-1, x2, y2)
        else
            if dir == -1 and pl < y1
                aZZ.x.set(0, x2), aZZ.y.set(0, y2)
        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()
    // FIX #2 : MSS appelé UNE SEULE FOIS au lieu d'être dupliqué
    detect_mss()
draw(len, color.yellow)
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()
ny        = (not na(time(timeframe.period, input.session('0700-0900', '', inline='ny', group='Killzones'), 'America/New_York'))) and showNy
ldn_open  = (not na(time(timeframe.period, input.session('0700-1000', '', inline='lo', group='Killzones'), 'Europe/London')))    and showLdno
ldn_close = (not na(time(timeframe.period, input.session('1500-1700', '', inline='lc', group='Killzones'), 'Europe/London')))    and showLdnc
asian     = (not na(time(timeframe.period, input.session('1000-1400', '', inline='as', group='Killzones'), 'Asia/Tokyo')))       and showAsia
ph2 = ta.pivothigh(3, 1), lPh = fixnan(ph2)
pl2 = ta.pivotlow (3, 1), lPl = fixnan(pl2)
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)
lwst = math.min(lPh[bsNOTbodyUP[1]], low[bsNOTbodyUP[1]])
hgst = math.max(high[bsNOTbodyDN[1]], lPl[bsNOTbodyDN[1]])
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])
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()
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, n))
        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, n))
        bFVG_DN.pop().box.delete()
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 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
newDay = ta.change(time("D")) != 0
if newDay
    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()
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)
[top, btm] = swings(ob_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
    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
    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)
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()
    if showBull > 0 and bullish_ob.size() > 0
        for i = 0 to math.min(showBull, bullish_ob.size())-1
            bullish_ob.get(i).display(bullCss, bullBrkCss, 'bl')
    if showBear > 0 and bearish_ob.size() > 0
        for i = 0 to math.min(showBear, bearish_ob.size())-1
            bearish_ob.get(i).display(bearCss, bearBrkCss, 'br')
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()
        '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
    if iFib != 'NONE'
        rt = math.max(x1,x2), _0 = rt==x1?y1:y2, _1 = rt==x1?y2:y1
        df = _1 - _0
        _diag.setLine(x1,y1,x2,y2)
        _zero.setLine(rt,_0,rt+plus,_0)
        _0236.setLine(rt,_0+df*0.236,rt+plus,_0+df*0.236)
        _0382.setLine(rt,_0+df*0.382,rt+plus,_0+df*0.382)
        _0500.setLine(rt,_0+df*0.500,rt+plus,_0+df*0.500)
        _0618.setLine(rt,_0+df*0.618,rt+plus,_0+df*0.618)
        _0786.setLine(rt,_0+df*0.786,rt+plus,_0+df*0.786)
        _one_.setLine(rt,_1,rt+plus,_1)
        _1618.setLine(rt,_0+df*1.618,rt+plus,_0+df*1.618)
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)
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)
//-----------------------------------------------------------------------------}
// TRINITY — Active OB selection + OTE live logic
//-----------------------------------------------------------------------------{
inRange(_v, _a, _b) => _v >= math.min(_a,_b) and _v <= math.max(_a,_b)
// _min_bar : seuls les FVGs créés APRÈS la détection de l'OB sont pris en compte
fvgInOTE(_arr, _lo, _hi, _min_bar) =>
    result = false
    if _arr.size() > 0
        for i = 0 to _arr.size()-1
            f = _arr.get(i)
            if f.active and f.pos >= _min_bar
                if f.box.get_bottom() <= _hi and f.box.get_top() >= _lo
                    result := true
                    break
    result
bool mssFlippedBull = MSS.dir == 1  and prevMSSdir != 1
bool mssFlippedBear = MSS.dir == -1 and prevMSSdir != -1
if mssFlippedBull
    ote_sel_lo := na
    ote_sel_hi := na
    ts_obLoc   := na
    ts_obBtm   := na
    ts_obTop   := na
    ts_swingLo := na
    ts_mssOk   := false
    if not na(ts_oteBox)
        ts_oteBox.delete()
        ts_oteBox := na
if mssFlippedBear
    ote_buy_lo := na
    ote_buy_hi := na
    tl_obLoc   := na
    tl_obBtm   := na
    tl_obTop   := na
    tl_swingHi := na
    tl_mssOk   := false
    if not na(tl_oteBox)
        tl_oteBox.delete()
        tl_oteBox := na
prevMSSdir := MSS.dir
float activeBullOB_btm = na
float activeBullOB_top = na
int   activeBullOB_loc = na
if MSS.dir == 1 and bullish_ob.size() > 0
    for i = 0 to bullish_ob.size()-1
        ob_item = bullish_ob.get(i)
        if not ob_item.breaker
            activeBullOB_btm := ob_item.btm
            activeBullOB_top := ob_item.top
            activeBullOB_loc := ob_item.loc
            break
float activeBearOB_btm = na
float activeBearOB_top = na
int   activeBearOB_loc = na
if MSS.dir == -1 and bearish_ob.size() > 0
    for i = 0 to bearish_ob.size()-1
        ob_item = bearish_ob.get(i)
        if not ob_item.breaker
            activeBearOB_btm := ob_item.btm
            activeBearOB_top := ob_item.top
            activeBearOB_loc := ob_item.loc
            break
if not na(activeBullOB_loc) and (na(tl_obLoc) or activeBullOB_loc != tl_obLoc)
    tl_obLoc   := activeBullOB_loc
    tl_obBtm   := activeBullOB_btm
    tl_obTop   := activeBullOB_top
    tl_swingHi := high
    tl_mssOk   := true
    tl_ob_bar  := bar_index
    ote_buy_lo := na
    ote_buy_hi := na
    if not na(tl_oteBox)
        tl_oteBox.delete()
        tl_oteBox := na
if na(activeBullOB_loc) and not na(tl_obLoc)
    tl_obLoc   := na
    tl_obBtm   := na
    tl_obTop   := na
    tl_swingHi := na
    tl_mssOk   := false
    ote_buy_lo := na
    ote_buy_hi := na
    if not na(tl_oteBox)
        tl_oteBox.delete()
        tl_oteBox := na
if not na(activeBearOB_loc) and (na(ts_obLoc) or activeBearOB_loc != ts_obLoc)
    ts_obLoc   := activeBearOB_loc
    ts_obBtm   := activeBearOB_btm
    ts_obTop   := activeBearOB_top
    ts_swingLo := low
    ts_mssOk   := true
    ts_ob_bar  := bar_index
    ote_sel_lo := na
    ote_sel_hi := na
    if not na(ts_oteBox)
        ts_oteBox.delete()
        ts_oteBox := na
if na(activeBearOB_loc) and not na(ts_obLoc)
    ts_obLoc   := na
    ts_obBtm   := na
    ts_obTop   := na
    ts_swingLo := na
    ts_mssOk   := false
    ote_sel_lo := na
    ote_sel_hi := na
    if not na(ts_oteBox)
        ts_oteBox.delete()
        ts_oteBox := na
if not na(tl_obLoc)
    tl_swingHi := na(tl_swingHi) ? high : math.max(tl_swingHi, high)
if not na(ts_obLoc)
    ts_swingLo := na(ts_swingLo) ? low  : math.min(ts_swingLo, low)
if not na(tl_obBtm) and not na(tl_swingHi) and tl_swingHi > tl_obBtm
    _rng       = tl_swingHi - tl_obBtm
    ote_buy_lo := tl_swingHi - _rng * ote_fib2
    ote_buy_hi := tl_swingHi - _rng * ote_fib1
if not na(ts_obTop) and not na(ts_swingLo) and ts_swingLo < ts_obTop
    _rng       = ts_obTop - ts_swingLo
    ote_sel_lo := ts_swingLo + _rng * ote_fib1
    ote_sel_hi := ts_swingLo + _rng * ote_fib2
//-----------------------------------------------------------------------------}
// OTE BOX DISPLAY
//-----------------------------------------------------------------------------{
if not na(ote_buy_lo) and not na(ote_buy_hi) and per and MSS.dir == 1
    _left  = na(tl_obLoc) ? time : tl_obLoc
    _right = timenow + tf_msec * 20
    if na(tl_oteBox)
        tl_oteBox := box.new(_left, ote_buy_hi, _right, ote_buy_lo, bgcolor=cOTEbull, border_color=color.new(#00e676,40), text='OTE', text_size=size.tiny, xloc=xloc.bar_time)
    else
        tl_oteBox.set_left(_left)
        tl_oteBox.set_top(ote_buy_hi)
        tl_oteBox.set_bottom(ote_buy_lo)
        tl_oteBox.set_right(_right)
else if not na(tl_oteBox)
    tl_oteBox.delete()
    tl_oteBox := na
if not na(ote_sel_lo) and not na(ote_sel_hi) and per and MSS.dir == -1
    _left  = na(ts_obLoc) ? time : ts_obLoc
    _right = timenow + tf_msec * 20
    if na(ts_oteBox)
        ts_oteBox := box.new(_left, ote_sel_hi, _right, ote_sel_lo, bgcolor=cOTEbear, border_color=color.new(#ff5252,40), text='OTE', text_size=size.tiny, xloc=xloc.bar_time)
    else
        ts_oteBox.set_left(_left)
        ts_oteBox.set_top(ote_sel_hi)
        ts_oteBox.set_bottom(ote_sel_lo)
        ts_oteBox.set_right(_right)
else if not na(ts_oteBox)
    ts_oteBox.delete()
    ts_oteBox := na
//-----------------------------------------------------------------------------}
// TRINITY SIGNAL
//-----------------------------------------------------------------------------{
var bool  tl_fired     = false
var bool  ts_fired     = false
var int   tl_signal_ob = na   // OB qui a déclenché le dernier TL
var int   ts_signal_ob = na   // OB qui a déclenché le dernier TS
var label tl_lbl       = na   // label unique TL (1 seul sur le chart)
var label ts_lbl       = na   // label unique TS (1 seul sur le chart)

// Reset sur flip MSS + effacement du label de l'autre côté
if mssFlippedBear
    tl_fired     := false
    tl_signal_ob := na
    if not na(ts_lbl)
        ts_lbl.delete()
        ts_lbl := na
if mssFlippedBull
    ts_fired     := false
    ts_signal_ob := na
    if not na(tl_lbl)
        tl_lbl.delete()
        tl_lbl := na

// Reset si l'OB actif a changé depuis le dernier signal (nouveau setup)
if tl_fired and not na(tl_signal_ob) and tl_obLoc != tl_signal_ob
    tl_fired := false
if ts_fired and not na(ts_signal_ob) and ts_obLoc != ts_signal_ob
    ts_fired := false

// Signal : OB détecté + MSS aligné + FVG dans la zone OTE calculée
// Le prix N'A PAS besoin d'entrer dans l'OTE
fvgInOTE_buy  = not na(ote_buy_lo) and fvgInOTE(bFVG_UP, ote_buy_lo, ote_buy_hi, tl_ob_bar)
fvgInOTE_sell = not na(ote_sel_lo) and fvgInOTE(bFVG_DN, ote_sel_lo, ote_sel_hi, ts_ob_bar)
bool tri_long_raw  = tl_mssOk and not na(tl_obLoc) and fvgInOTE_buy  and not tl_fired
bool tri_short_raw = ts_mssOk and not na(ts_obLoc) and fvgInOTE_sell and not ts_fired
bool tri_long  = tri_close ? (tri_long_raw  and barstate.isconfirmed) : tri_long_raw
bool tri_short = tri_close ? (tri_short_raw and barstate.isconfirmed) : tri_short_raw

if tri_long
    tl_fired     := true
    tl_signal_ob := tl_obLoc
    if not na(tl_lbl)
        tl_lbl.delete()
    tl_lbl := label.new(tl_obLoc, tl_obBtm, 'TL', xloc=xloc.bar_time, style=label.style_label_up, color=color.new(color.lime,0), textcolor=color.white, size=size.small)
    alert('TRINITY LONG SETUP | ' + syminfo.ticker + ' | ' + timeframe.period + 'min | OB+MSS+FVG alignés | Prix: ' + str.tostring(close), alert.freq_once_per_bar)
if tri_short
    ts_fired     := true
    ts_signal_ob := ts_obLoc
    if not na(ts_lbl)
        ts_lbl.delete()
    ts_lbl := label.new(ts_obLoc, ts_obTop, 'TS', xloc=xloc.bar_time, style=label.style_label_down, color=color.new(color.red,0), textcolor=color.white, size=size.small)
    alert('TRINITY SHORT SETUP | ' + syminfo.ticker + ' | ' + timeframe.period + 'min | OB+MSS+FVG alignés | Prix: ' + str.tostring(close), alert.freq_once_per_bar)
alertcondition(tri_long or tri_short, 'TRINITY Signal', message='TRINITY SIGNAL')

Overview

A mode setting switches between showing only recent elements and historical ones. Swing length, the number of visible order blocks, liquidity boxes and imbalances, and colors are adjustable. The script credits LuxAlgo-derived code. It draws on the price chart and does not generate entries or exits.

Details

Published by

sam56100 on GitHub

Code credit

SAMANYFX / © LuxAlgo, as written in the script's header

Type

Indicator, Pine Script v6

Draws

On the price chart

Category

SMC / ICT / price action, Support & resistance

Markets

Any symbol

Timeframes

Any timeframe

Risk Notes

No repainting, lookahead or stacked entries were found in its code or README. That says nothing about how well it works: test it first.

Settings

The inputs you can change from the gear icon on the chart. Defaults are the author's.

SettingTypeDefaultVariable
ModestringPresenti_mode
showMSbooltrueshowMS
lenint5len
iMSSbooltrueiMSS
bullishcolorcolor.new(#00e6a1, 0)cMSSbl
bearishcolorcolor.new(#e60400, 0)cMSSbr
iBOSbooltrueiBOS
bullishcolorcolor.new(#00e6a1, 0)cBOSbl
bearishcolorcolor.new(#e60400, 0)cBOSbr
Show DisplacementboolfalsesDispl
sVimblbooltruesVimbl
visVimint2visVim
Show all 40 settings
SettingTypeDefaultVariable
cVimblcolorcolor.new(#06b2d0, 0)cVimbl
Show Order BlocksbooltrueshowOB
Swing Lookbackint10ob_length
Show Last Bullish OBint1showBull
Show Last Bearish OBint1showBear
Use Candle BodyboolfalseuseBody
Bullish OBcolorcolor.new(#3e89fa, 0)bullCss
Bullish Breakcolorcolor.new(#4785f9, 85)bullBrkCss
Bearish OBcolorcolor.new(#FF3131, 0)bearCss
Bearish Breakcolorcolor.new(#f9ff57, 85)bearBrkCss
Show Historical Polarity ChangesboolfalseshowLabels
Show LiquiditybooltrueshowLq
marginfloat4margin
# Visible Liq. boxesint2visLiq
Buyside Liquidity colorcolor.new(#fa451c, 0)cLIQ_B
Sellside Liquiditycolorcolor.new(#1ce4fa, 0)cLIQ_S
Show FVGsbooltrueshwFVG
Balance Price Rangeboolfalsei_BPR
i_FVGstringFVGi_FVG
# Visible FVG'sint2visBxs
Bullish FVG colorcolor.new(#00e676, 0)cFVGbl
Breakcolorcolor.new(#808000, 0)cFVGblBR
Bearish FVG colorcolor.new(#ff5252, 0)cFVGbr
Breakcolorcolor.new(#FF0000, 0)cFVGbrBR
iNWOGbooltrueiNWOG
NWOG colorcolor.new(#ff5252, 28)cNWOG1
cNWOG2colorcolor.new(#b2b5be, 50)cNWOG2
Show maxint3maxNWOG
Third-party code. ForexR did not write, test or endorse this script, and the summary above was generated automatically from its code and README. Indicators describe the past, and a strategy's backtest can look better than live trading, especially when a script repaints. Check it in the Strategy Tester and on a demo account before you rely on it.

Similar Pine Scripts

ICT Equal Highs and Lows

by ArunKBhaskar
575 stars

This overlay indicator finds pivot highs and lows on the price chart and compares the last two highs and the last two lows. When the percentage difference between a pair is below the Equal HL threshold, it treats them as equal levels and draws a box. Left and

Indicator v5 SMC / ICT / price actionSupport & resistance
Updated 1 year ago · MPL-2.0 GitHub repository of ICT Equal Highs and Lows

DE-tracker

by Allen1212
303 stars

This indicator plots labels on the TradingView price chart to mark ARK Invest's buy and sell trades for the DE stock. Buy transactions appear in green with X1 or X2 multipliers showing the number of ARK ETFs involved on the same day; sells appear in red. The m

Indicator v4 Support & resistanceSMC / ICT / price action
Updated 2 years ago · None stated GitHub repository of DE-tracker

This Pine Script indicator plots a ZigZag on the price chart. It identifies reversal points when price moves more than a set percentage from the last pivot. The script calculates forecasts using zigzag data and labels detected geometric patterns including harm

Indicator v4 TrendSupport & resistance

Golden Bullet Strategy

by TradersPost
218 stars

The Golden Bullet Strategy is an overlay signal indicator based on Smart Money Concepts and time-based liquidity models. It identifies liquidity sweeps of a designated reference session range during a specified hunt window. It then confirms Market Structure Sh

Indicator v6 SMC / ICT / price actionSessions & time
Updated 3 months ago · None stated GitHub repository of Golden Bullet Strategy

Open Source Fractal

by cantolab
183 stars

This indicator implements the Fractal Model concept to plot market structure shifts, liquidity sweeps, and Change in State of Delivery (CISD) levels. It overlays custom higher-timeframe candle previews, open prices, and time markers directly on the price chart

Indicator v6 SMC / ICT / price actionSupport & resistance
Updated 2 months ago · MIT GitHub repository of Open Source Fractal

Swing Failure Signals

by Ganador1
154 stars

This indicator calculates pivot highs and pivot lows to detect liquidity sweeps and Swing Failure Patterns. It identifies when price breaks past recent key swing highs or lows within a configurable historical window, then looks for a quick reversal or change i

Indicator v6 SMC / ICT / price actionSupport & resistance
Updated 2 months ago · Apache-2.0 GitHub repository of Swing Failure Signals

More indicators

Trade Your Charts With a Regulated Broker

Compare brokers that connect to TradingView, with spreads, minimum deposits and leverage side by side.

Compare brokers