Price Action Concepts
Price Action Concepts
  , overlay = true
  , max_labels_count = 500
  , max_lines_count = 500
  , max_boxes_count = 500
  , max_bars_back = 500)
//-----------------------------------------------------------------------------{
//Constants
//-----------------------------------------------------------------------------{
color TRANSP_CSS = #ffffff00
//Tooltips
string MODE_TOOLTIP          = 'Allows to display historical Structure or only the
recent ones'
string STYLE_TOOLTIP         = 'Indicator color theme'
string COLOR_CANDLES_TOOLTIP = 'Display additional candles with a color reflecting
the current trend detected by structure'
string SHOW_INTERNAL         = 'Display internal market structure'
string CONFLUENCE_FILTER     = 'Filter non significant internal structure
breakouts'
string SHOW_SWING            = 'Display swing market Structure'
string SHOW_SWING_POINTS     = 'Display swing point as labels on the chart'
string SHOW_SWHL_POINTS      = 'Highlight most recent strong and weak high/low
points on the chart'
string INTERNAL_OB           = 'Display internal order blocks on the chart\n\
nNumber of internal order blocks to display on the chart'
string SWING_OB              = 'Display swing order blocks on the chart\n\nNumber
of internal swing blocks to display on the chart'
string FILTER_OB             = 'Method used to filter out volatile order blocks \n\
nIt is recommended to use the cumulative mean range method when a low amount of
data is available'
string SHOW_EQHL             = 'Display equal highs and equal lows on the chart'
string EQHL_BARS             = 'Number of bars used to confirm equal highs and
equal lows'
string EQHL_THRESHOLD        = 'Sensitivity threshold in a range (0, 1) used for
the detection of equal highs & lows\n\nLower values will return fewer but more
pertinent results'
string SHOW_FVG              = 'Display fair values gaps on the chart'
string AUTO_FVG              = 'Filter out non significant fair value gaps'
string FVG_TF                = 'Fair value gaps timeframe'
string EXTEND_FVG            = 'Determine how many bars to extend the Fair Value
Gap boxes on chart'
string PED_ZONES             = 'Display premium, discount, and equilibrium zones on
chart'
//-----------------------------------------------------------------------------{
//Settings
//-----------------------------------------------------------------------------{
//General
//----------------------------------------{
mode = input.string("Historical", "MS Mode", options = ["Historical", "Present"],
group = "Internal Structure")
style = 'Colored'
//----------------------------------------}
//Internal Structure
//----------------------------------------{
show_internals = input(true, 'Show Internal Structure'
  , group = 'Internal Structure'
  , tooltip = SHOW_INTERNAL)
//Bear Structure
show_ibear = show_ibull
ifilter_confluence = false
internal_structure_size = 'Tiny'
//----------------------------------------}
//Swing Structure
//----------------------------------------{
show_Structure = input(true, 'Show Swing Structure'
  , group = 'Swing Structure'
  , tooltip = SHOW_SWING)
//Bull Structure
show_bull = input.string('All', 'Structure Type'
  , options = ['All', 'BOS', 'CHoCH']
  , inline = 'bull'
  , group = 'Swing Structure')
//Bear Structure
show_bear = show_bull
swing_structure_size = 'Small'
//Swings
show_swings = input(false, 'Show Swings Points'
  , inline = 'swings'
  , group = 'Swing Structure'
  , tooltip = SHOW_SWING_POINTS)
showInvalidated = false
OBsEnabled = true
orderBlockVolumetricInfo = true
obEndMethod = input.string("Wick", "Mitigation Method", options = ["Wick",
"Close"], group = "Volumetric Orderblocks", display = display.none)
combineOBs = true
maxATRMult = 10.
swingLength = input.int(10, 'Construction Length', minval = 3, tooltip="Swing
length is used when finding order block formations. Smaller values will result in
finding smaller order blocks.",group = "Volumetric Orderblocks", display =
display.none, inline = "obColor")
show_sd = showEntryZones
premium_css = swing_bear_css
eq_css = #b2b5be
discount_css = swing_bull_css
//----------------------------------------}
//Order Blocks
//----------------------------------------{
var int candlecolor = 0
//----------------------------------------}
//Price Action Concepts
//----------------------------------------{
activateliquidity = input.bool(false, inline = "Sweeps", group = "Liquidity
Concepts", title = "Liquidity Sweeps")
len12345    = input.int(3, '', options = [1, 2, 3, 4, 5], group = 'Liquidity
Concepts', inline = "Sweeps")
opt    = 'Only Wicks'
len12345 := len12345 * 2
extend   =   false
maxB     =   300
colBl3   =   colBl
colBr3   =   colBr
n = bar_index
//-----------------------------------------------------------------------------}
//UDT's
//-----------------------------------------------------------------------------{
type piv
    float prc // price
    int   bix // bar_index
    bool brk // broken
    bool   mit // mitigated
    bool   tak // taken
    bool   wic // wick
    line   lin
type boxBr
    box bx
    line ln
    bool br
    int dr
//-----------------------------------------------------------------------------}
//Variables
//-----------------------------------------------------------------------------{
var array< piv >aPivH = array.new< piv >(1, piv.new ())
var array< piv >aPivL = array.new< piv >(1, piv.new ())
var array<boxBr>aBoxBr = array.new<boxBr>(1, boxBr.new())
//-----------------------------------------------------------------------------}
//Methods - functions
//-----------------------------------------------------------------------------{
method n(float piv) => bool out = not na(piv)
method p(piv piv, float val) => float out = (100 / piv.prc * val) - 100
//-----------------------------------------------------------------------------}
//Execution
//-----------------------------------------------------------------------------{
ph = ta.pivothigh(len12345, len12345)
pl = ta.pivotlow (len12345, len12345)
if ph.n()
    aPivH.unshift(piv.new(ph, n -len12345, false, false, false, false))
if pl.n()
    aPivL.unshift(piv.new(pl, n -len12345, false, false, false, false))
bool bullcandle = false
bool bearcandle = false
for i = aPivH.size() -1 to 0
    get = aPivH.get(i)
    if not get.mit
        if not get.brk
            if close > get.prc
                if not oW
                     get.brk := true
                else
                     get.mit := true
            if not oO and not get.wic
                if high > get.prc and close < get.prc
                     bearcandle := true
                    get.wic := true
        else
            if close < get.prc
                get.mit := true
            if not oW and low < get.prc and close > get.prc
get.tak := true
                    get.wic := true
        else
            if close > get.prc
                get.mit := true
            if not oW and high > get.prc and close < get.prc
get.tak := true
//-----------------------------------------------------------------------------}
len123 := len123 * 2
phhh = ta.pivothigh(high, len123, len123)
plll = ta.pivotlow (low , len123, len123)
type store
    float src
    int    n
type bar
    float   o   =   open
    float   h   =   high
    float   l   =   low
    float   c   =   close
    int     n   =   bar_index
    float   v   =   volume
type draw
    line[] upln
    line[] dnln
bar b = bar.new()
atr   = ta.atr(200)
vol() =>
    math.min(atr * 0.1, close * (0.1/100))
    upbin.unshift(store.new(b.h[len12345], b.n[len12345]))
    if upbin.size() > 1
        current = upbin.get(0)
        before = upbin.get(1)
        if current.src < before.src
            if broken
                valid := true
             else
                valid := false
                if upbin.size() > 3
                    pastold = upbin.get(3)
                    pastcur = upbin.get(2)
                    now      = upbin.get(1)
                    late     = upbin.get(0)
                    if now.src < pastcur.src and now.src < pastold.src and late.src
< pastcur.src and late.src < pastold.src
                         valid := true
                     else
                         valid := false
                 else
                     valid := false
if valid
                 ln = d.upln.get(1)
                 for i = 0 to (b.n - before.n)
                     slope = ln.slope()
                     ln.set_x2(b.n[i])
                     ln.set_y2(ln.get_y2() - slope)
                     if low[i] > ln.get_y2()
                         remove := true
                         break
                 if remove
                     d.upln.get(0).delete()
                     d.upln.get(1).delete()
                     d.upln       .clear()
                     upbin        .clear()
                     broken := true
                 else
                      d.upln.get(0).delete()
                      d.upln.get(1).delete()
                      d.upln       .clear ()
if d.upln.size() > 1
    btm = d.upln.get(0)
    top = d.upln.get(1)
if d.upln.size() > 1
        slup = top.slope()
        sldn = btm.slope()
        top.set_x2(b.n)
        top.set_y2(top.get_y2() + slup)
        btm.set_x2(b.n)
        btm.set_y2(btm.get_y2() + sldn)
    dnbin.unshift(store.new(b.l[len12345], b.n[len12345]))
    if dnbin.size() > 1
        current = dnbin.get(0)
        before = dnbin.get(1)
        if current.src > before.src
            if broken
                valid := true
             else
                 valid := false
                 if dnbin.size() > 3
                     pastold = dnbin.get(3)
                     pastcur = dnbin.get(2)
                     now     = dnbin.get(1)
                     late    = dnbin.get(0)
                    if now.src > pastcur.src and now.src > pastold.src and late.src
> pastcur.src and late.src > pastold.src
                        valid := true
                      else
                          valid := false
                else
                      valid := false
            if valid
                d.dnln.unshift(line.new(x1 = before.n, x2 = current.n, y1 =
before.src                , y2 = current.src                , color = cup))
                d.dnln.unshift(line.new(x1 = before.n, x2 = current.n, y1 =
before.src + vol() * space, y2 = current.src + vol() * space, color = cup))
ln = d.dnln.get(1)
                if remove
                    d.dnln.get(0).delete()
                    d.dnln.get(1).delete()
                    d.dnln       .clear ()
                    dnbin        .clear ()
                    broken := true
                else
                      d.dnln.get(0).delete()
                      d.dnln.get(1).delete()
                      d.dnln       .clear ()
if d.dnln.size() > 1
    btm = d.dnln.get(0)
    top = d.dnln.get(1)
           slup = top.slope()
           sldn = btm.slope()
           top.set_x2(b.n)
           top.set_y2(top.get_y2() + slup)
           btm.set_x2(b.n)
           btm.set_y2(btm.get_y2() + sldn)
eq_threshold = 0.1*(6-eq_len)
if eq_len == 5
    eq_threshold == 0.05
eq_size = 'Tiny'
//Conditions
upupup = ta.pivothigh(csrcsrcsrc ? srcsrcsrc : high, length11111, length11111)
dndndn = ta.pivotlow(csrcsrcsrc ? srcsrcsrc : low, length111112, length111112)
//Colors
color111 = #a53e48
color222 = #5b8d5e
//Plots
if ontrendline
    line upupupper1 = line.new(n[n - a1 + length11111], upupup[n - a1]+atr10, n[n -
a2 + length11111], upupup[n - a2]+atr10, extend=extend.right,
color=color.new(color111, 10),width=1)
    line lower1 = line.new(n[n - b1 + length111112], dndndn[n - b1], n[n - b2 +
length111112], dndndn[n - b2], extend=extend.right, color=color.new(color222, 10),
width=1)
    line upupupper2 = line.new(n[n - a1 + length11111], upupup[n - a1], n[n - a2 +
length11111], upupup[n - a2], extend=extend.right, color=color.new(color111, 10),
width=1)
    line lower2 = line.new(n[n - b1 + length111112], dndndn[n - b1]-atr10, n[n - b2
+ length111112], dndndn[n - b2]-atr10, extend=extend.right,
color=color.new(color222, 10), width=1)
    linefill t = linefill.new(upupupper1, upupupper2, color.new(color111, 75))
    linefill y = linefill.new(lower1, lower2, color.new(color222, 75))
    line.delete(upupupper1[1])
    line.delete(lower1[1])
    line.delete(upupupper2[1])
    line.delete(lower2[1])
//----------------------------------------}
//Fair Value Gaps
//----------------------------------------{
//----------------------------------------}
//Previous day/week high/low
//----------------------------------------{
//Daily
show_pdhl = input(false, 'Daily'
  , inline = 'daily'
  , group = 'Highs & Lows MTF')
//Weekly
show_pwhl = input(false, 'Weekly'
  , inline = 'weekly'
  , group = 'Highs & Lows MTF')
//Monthly
show_pmhl = input(false, 'Monthly'
  , inline = 'monthly'
  , group = 'Highs & Lows MTF')
//----------------------------------------}
//Premium/Discount zones
//----------------------------------------{
//-----------------------------------------------------------------------------}
//Functions
//-----------------------------------------------------------------------------{
//n = bar_index
    if mode == 'Present'
        line.delete(structure_line[1])
        label.delete(structure_lbl[1])
//Swings detection/measurements
swings(len)=>
    var os = 0
    upper = ta.highest(len)
    lower = ta.lowest(len)
[top, btm]
    hy = ta.valuewhen(h != h[1], h, 1)
    hx = ta.valuewhen(h == high, time, 1)
    ly = ta.valuewhen(l != l[1], l, 1)
    lx = ta.valuewhen(l == low, time, 1)
    if barstate.islast
        ext = time + (time - time[1])*20
          //High
          line.set_xy1(high_line, hx, hy)
          line.set_xy2(high_line, ext, hy)
//-----------------------------------------------------------------------------}
//Global variables
//-----------------------------------------------------------------------------{
var trend = 0, var itrend = 0
//Alerts
bull_choch_alert = false
bull_bos_alert   = false
bear_choch_alert = false
bear_bos_alert   = false
bull_ichoch_alert = false
bull_ibos_alert   = false
bear_ichoch_alert = false
bear_ibos_alert   = false
bull_iob_break = false
bear_iob_break = false
bull_ob_break = false
bear_ob_break = false
eqh_alert = false
eql_alert = false
//Structure colors
var bull_css = style == 'Monochrome' ? #b2b5be
  : swing_bull_css
//Labels size
var internal_structure_lbl_size = internal_structure_size == 'Tiny'
  ? size.tiny
  : internal_structure_size == 'Small'
  ? size.small
  : size.normal
//Swings
[top, btm] = swings(length)
//-----------------------------------------------------------------------------}
//Pivot High
//-----------------------------------------------------------------------------{
var line extend_top = na
if top
    top_cross := true
    txt_top := top > top_y ? 'HH' : 'LH'
      if show_swings
          top_lbl = label.new(n-length, top, txt_top
            , color = TRANSP_CSS
            , textcolor = bear_css
            , style = label.style_label_down
            , size = swing_structure_lbl_size)
          if mode == 'Present'
              label.delete(top_lbl[1])
      if show_hl_swings
          extend_top := line.new(n-length, top, n, top     , color = bear_css)
      top_y := top
      top_x := n - length
      trail_up := top
      trail_up_x := n - length
if itop
    itop_cross := true
      itop_y := itop
      itop_x := n - 5
//Trailing maximum
trail_up := math.max(high, trail_up)
trail_up_x := trail_up == high ? n : trail_up_x
      label.set_x(extend_top_lbl, n + 20)
      label.set_y(extend_top_lbl, trail_up)
      label.set_text(extend_top_lbl, trend < 0 ? 'Strong High' : 'Weak High')
//-----------------------------------------------------------------------------}
//Pivot Low
//-----------------------------------------------------------------------------{
var line extend_btm = na
if btm
    btm_cross := true
    txt_btm := btm < btm_y ? 'LL' : 'HL'
      if show_swings
          btm_lbl = label.new(n - length, btm, txt_btm
            , color = TRANSP_CSS
            , textcolor = bull_css
            , style = label.style_label_up
            , size = swing_structure_lbl_size)
          if mode == 'Present'
              label.delete(btm_lbl[1])
      btm_y := btm
      btm_x := n-length
      trail_dn := btm
      trail_dn_x := n-length
if ibtm
    ibtm_cross := true
      ibtm_y := ibtm
      ibtm_x := n - 5
//Trailing minimum
trail_dn := math.min(low, trail_dn)
trail_dn_x := trail_dn == low ? n : trail_dn_x
      label.set_x(extend_btm_lbl, n + 20)
      label.set_y(extend_btm_lbl, trail_dn)
      label.set_text(extend_btm_lbl, trend > 0 ? 'Strong Low' : 'Weak Low')
//-----------------------------------------------------------------------------}
//Order Blocks Arrays
//-----------------------------------------------------------------------------{
var iob_top = array.new_float(0)
var iob_btm = array.new_float(0)
var iob_left = array.new_int(0)
var iob_type = array.new_int(0)
//-----------------------------------------------------------------------------}
//Pivot High BOS/CHoCH
//-----------------------------------------------------------------------------{
//Filtering
var bull_concordant = true
if ifilter_confluence
    bull_concordant := high - math.max(close, open) > math.min(close, open - low)
      if itrend < 0
           choch := true
           candlecolor := 0
           bull_ichoch_alert := true
      else
           bull_ibos_alert := true
           candlecolor := 1
    if show_internals
        if show_ibull == 'All' or (show_ibull == 'BOS' and not choch) or
(show_ibull == 'CHoCH' and choch)
            display_Structure(itop_x, itop_y, txt, ibull_css, true, true,
internal_structure_lbl_size)
    itop_cross := false
    itrend := 1
    if trend < 0
         choch := true
         bull_choch_alert := true
    else
         bull_bos_alert := true
//Order Block
    top_cross := false
    trend := 1
    swingtrend := 1
//-----------------------------------------------------------------------------}
//Pivot Low BOS/CHoCH
//-----------------------------------------------------------------------------{
var bear_concordant = true
if ifilter_confluence
    bear_concordant := high - math.max(close, open) < math.min(close, open - low)
    if itrend > 0
        choch := true
        bear_ichoch_alert := true
          candlecolor := 0
    else
          bear_ibos_alert := true
          candlecolor := -1
    ibtm_cross := false
    itrend := -1
    if trend > 0
         choch := true
         bear_choch_alert := true
    else
         bear_bos_alert := true
//Order Block
    btm_cross := false
    trend := -1
    swingtrend := -1
//-----------------------------------------------------------------------------}
//Order Blocks
//-----------------------------------------------------------------------------{
//Set order blocks
textColor = color.white
extendZonesBy = DEBUG ? input.int(15, "Extend Zones", group = "Style", minval = 1,
maxval = 30, inline = "ExtendZones") : 15
extendZonesDynamic = DEBUG ? input.bool(true, "Dynamic", group = "Style", inline =
"ExtendZones") : true
combinedText = DEBUG ? input.bool(false, "Combined Text", group = "Style", inline =
"CombinedColor") : false
volumeBarsPlace = DEBUG ? input.string("Left", "Show Volume Bars At", options =
["Left", "Right"], group = "Style", inline = "volumebars") : "Left"
mirrorVolumeBars = DEBUG ? input.bool(true, "Mirror Volume Bars", group = "Style",
inline = "volumebars") : true
atrt = ta.atr(10)
type orderBlockInfo
    float top
    float bottom
    float obVolume
    string obType
    int startTime
    float bbVolume
    float obLowVolume
    float obHighVolume
    bool breaker
    int breakTime
    string timeframeStr
    bool disabled = false
    string combinedTimeframesStr = na
    bool combined = false
type orderBlock
    orderBlockInfo info
    bool isRendered = false
    box orderBox = na
    box breakerBox = na
    line orderBoxLineTop = na
    line orderBoxLineBottom = na
    line breakerBoxLineTop = na
    line breakerBoxLineBottom = na
    //
    box orderBoxText = na
    box orderBoxPositive = na
    box orderBoxNegative = na
    line orderSeperator = na
    line orderTextSeperator = na
    box.delete(orderBlockF.orderBox)
    box.delete(orderBlockF.breakerBox)
    box.delete(orderBlockF.orderBoxText)
    box.delete(orderBlockF.orderBoxPositive)
    box.delete(orderBlockF.orderBoxNegative)
    line.delete(orderBlockF.orderBoxLineTop)
    line.delete(orderBlockF.orderBoxLineBottom)
    line.delete(orderBlockF.breakerBoxLineTop)
    line.delete(orderBlockF.breakerBoxLineBottom)
    line.delete(orderBlockF.orderSeperator)
    line.delete(orderBlockF.orderTextSeperator)
type timeframeInfo
    int index = na
    string timeframeStr = na
    bool isEnabled = false
    orderBlockInfo[] bullishOrderBlocksList = na
    orderBlockInfo[] bearishOrderBlocksList = na
newTFInfo
type obSwing
    int x = na
    float y = na
    float swingVolume = na
    bool crossed = false
    if OBsEnabled and (not false or not (false and info.breaker)) and not (not
showInvalidated and info.breaker) and ob.info.disabled == false
        ob.orderBox := createOBBox(orderColor, transp)
        box.set_extend(ob.orderBox, extend.right)
        if ob.info.combined
            ob.orderBox.set_bgcolor(color.new(orderColor, transp))
        ob.orderBoxText := createOBBox(orderColor)
        if orderBlockVolumetricInfo
            ob.orderBoxPositive := createOBBox(bullOrderBlockColor, 30)
            ob.orderBoxNegative := createOBBox(bearOrderBlockColor, 30)
            ob.orderSeperator :=
line.new(na,na,na,na,xloc.bar_time,extend.none,orderColor,line.style_dashed,1)
            //ob.orderTextSeperator := line.new(na,na,
na,na,xloc.bar_index,extend.none,orderColor,line.style_solid,1)
        if orderBlockVolumetricInfo
            showHighLowBoxText = false
            //line.set_xy1(ob.orderTextSeperator, barstate.isconfirmed ?
bar_index+1 : bar_index+1, info.top)
            //line.set_xy2(ob.orderTextSeperator, barstate.isconfirmed ?
bar_index+1 : bar_index+1, info.bottom)
            //line.set_color(ob.orderTextSeperator, orderColor)
findOBSwings(len) =>
    var swingType = 0
    var obSwing top = obSwing.new(na, na)
    var obSwing bottom = obSwing.new(na, na)
    upper = ta.highest(len)
    lower = ta.lowest(len)
[top, bottom]
findOrderBlocks () =>
    if bar_index > last_bar_index - maxDistanceToLastBar
        [top, btm] = findOBSwings(swingLength)
        useBody = false
        max = useBody ? math.max(close, open) : high
        min = useBody ? math.min(close, open) : low
        if bullishOrderBlocksList.size() > 0
            for i = bullishOrderBlocksList.size() - 1 to 0
                currentOB = bullishOrderBlocksList.get(i)
                if not currentOB.breaker
                    if (obEndMethod == "Wick" ? low : math.min(open, close)) <
currentOB.bottom
                        currentOB.breaker := true
                        currentOB.breakTime := time
                        currentOB.bbVolume := volume
                else
                    if high > currentOB.top
                         bullishOrderBlocksList.remove(i)
                    else if i < bullishOrderBlocks and top.y < currentOB.top and
top.y > currentOB.bottom
                         bullishBreaked := 1
            boxBtm = max[1]
            boxTop = min[1]
            boxLoc = time[1]
bearishBreaked = 0
        if bearishOrderBlocksList.size() > 0
            for i = bearishOrderBlocksList.size() - 1 to 0
                currentOB = bearishOrderBlocksList.get(i)
                if not currentOB.breaker
                    if (obEndMethod == "Wick" ? high : math.max(open, close)) >
currentOB.top
                        currentOB.breaker := true
                        currentOB.breakTime := time
                        currentOB.bbVolume := volume
                else
                    if low < currentOB.bottom
                        bearishOrderBlocksList.remove(i)
                    else if i < bearishOrderBlocks and btm.y > currentOB.bottom and
btm.y < currentOB.top
                        bearishBreaked := 1
            boxBtm = min[1]
            boxTop = max[1]
            boxLoc = time[1]
combineOBsFunc () =>
    if allOrderBlocksList.size() > 0
        lastCombinations = 999
        while lastCombinations > 0
            lastCombinations := 0
            for i = 0 to allOrderBlocksList.size() - 1
                curOB1 = allOrderBlocksList.get(i)
                for j = 0 to allOrderBlocksList.size() - 1
                     curOB2 = allOrderBlocksList.get(j)
                     if i == j
                         continue
                     if not isOBValid(curOB1.info) or not isOBValid(curOB2.info)
                         continue
                     if curOB1.info.obType != curOB2.info.obType
                         continue
                     if doOBsTouch(curOB1.info, curOB2.info)
                         if curOB1.info.bottom < curOB2.info.top and curOB1.info.top
> curOB2.info.top
                             curOB2.info.top := curOB1.info.bottom
                            lastCombinations := lastCombinations + 1
                        if curOB1.info.top >= curOB2.info.top and
curOB1.info.bottom <= curOB2.info.bottom
                            curOB2.info.disabled := true
                            lastCombinations := lastCombinations + 1
handleOrderBlocksFinal () =>
    if DEBUG
        log.info("Bullish OB Count " + str.tostring(bullishOrderBlocksList.size()))
        log.info("Bearish OB Count " + str.tostring(bearishOrderBlocksList.size()))
    if allOrderBlocksList.size () > 0
        for i = 0 to allOrderBlocksList.size() - 1
            safeDeleteOrderBlock(allOrderBlocksList.get(i))
    allOrderBlocksList.clear()
    for i = 0 to timeframeInfos.size() - 1
        curTimeframe = timeframeInfos.get(i)
        if na(curTimeframe)
            continue
        if not curTimeframe.isEnabled
            continue
        if na(curTimeframe.bullishOrderBlocksList)
            continue
        if curTimeframe.bullishOrderBlocksList.size() > 0
            while curTimeframe.bullishOrderBlocksList.size() > bullishOrderBlocks
                curTimeframe.bullishOrderBlocksList.pop()
            for j = 0 to math.min(curTimeframe.bullishOrderBlocksList.size() - 1,
bullishOrderBlocks - 1)
                bool overlapped = false
                orderBlockInfoF = curTimeframe.bullishOrderBlocksList.get(j)
                orderBlockInfoF.timeframeStr := curTimeframe.timeframeStr
                if allOrderBlocksList.size() > 0
                     for t = 0 to allOrderBlocksList.size()-1
                         if doOBsTouch(orderBlockInfoF,
allOrderBlocksList.get(t).info)
                            overlapped := true
if overlapped == false
allOrderBlocksList.unshift(createOrderBlock(orderBlockInfo.copy(orderBlockInfoF)))
allOrderBlocksList.unshift(createOrderBlock(orderBlockInfo.copy(orderBlockInfoF)))
    if combineOBs
        combineOBsFunc()
    if allOrderBlocksList.size() > 0
        for i = 0 to allOrderBlocksList.size() - 1
            curOB = allOrderBlocksList.get(i)
            if isOBValid(curOB.info)
                renderOrderBlock(curOB)
findOrderBlocks()
currentTF = timeframe.period
[bullishOrderBlocksListTimeframe1, bearishOrderBlocksListTimeframe1] =
getTFData(timeframeInfos.get(0), timeframe1)
[bullishOrderBlocksListTimeframe2, bearishOrderBlocksListTimeframe2] =
getTFData(timeframeInfos.get(1), "15")
[bullishOrderBlocksListTimeframe3, bearishOrderBlocksListTimeframe3] =
getTFData(timeframeInfos.get(2), "1")
if barstate.isconfirmed
    if tfe(currentTF, timeframe1)
        handleTimeframeInfo(timeframeInfos.get(0),
bullishOrderBlocksListTimeframe1, bearishOrderBlocksListTimeframe1)
    if tfe(currentTF, "15")
        handleTimeframeInfo(timeframeInfos.get(1),
bullishOrderBlocksListTimeframe2, bearishOrderBlocksListTimeframe2)
    if tfe(currentTF, "1")
        handleTimeframeInfo(timeframeInfos.get(2),
bullishOrderBlocksListTimeframe3, bearishOrderBlocksListTimeframe3)
    handleOrderBlocksFinal()
//-----------------------------------------------------------------------------}
//Price Action Concepts
//-----------------------------------------------------------------------------{
var eq_prev_top = 0.
var eq_top_x = 0
var eq_prev_btm = 0.
var eq_btm_x = 0
if show_eq
    eq_top = ta.pivothigh(eq_len, eq_len)
    eq_btm = ta.pivotlow(eq_len, eq_len)
    if eq_top
        max = math.max(eq_top, eq_prev_top)
        min = math.min(eq_top, eq_prev_top)
            if mode == 'Present'
                line.delete(eqh_line[1])
                label.delete(eqh_lbl[1])
eqh_alert := true
        eq_prev_top := eq_top
        eq_top_x := n-eq_len
    if eq_btm
        max = math.max(eq_btm, eq_prev_btm)
        min = math.min(eq_btm, eq_prev_btm)
eql_alert := true
            if mode == 'Present'
                line.delete(eql_line[1])
                label.delete(eql_lbl[1])
          eq_prev_btm := eq_btm
          eq_btm_x := n-eq_len
//-----------------------------------------------------------------------------}
//Fair Value Gaps
//-----------------------------------------------------------------------------{
var bullish_fvg_max = array.new_box(0)
var bullish_fvg_min = array.new_box(0)
float bullish_fvg_avg = na
float bearish_fvg_avg = na
bullish_fvg_cnd = false
bearish_fvg_cnd = false
//-----------------------------------------------------------------------------}
//Previous day/week high/lows
//-----------------------------------------------------------------------------{
//Daily high/low
[pdh, pdl] = request.security(syminfo.tickerid, 'D', hl()
  , lookahead = barmerge.lookahead_on)
//Weekly high/low
[pwh, pwl] = request.security(syminfo.tickerid, 'W', hl()
  , lookahead = barmerge.lookahead_on)
//Monthly high/low
[pmh, pml] = request.security(syminfo.tickerid, 'M', hl()
  , lookahead = barmerge.lookahead_on)
//Display Daily
if show_pdhl
    phl(pdh, pdl, 'D', pdhl_css)
//Display Weekly
if show_pwhl
    phl(pwh, pwl, 'W', pwhl_css)
//Display Monthly
if show_pmhl
    phl(pmh, pml, 'M', pmhl_css)
//-----------------------------------------------------------------------------}
//Premium/Discount/Equilibrium zones
//-----------------------------------------------------------------------------{
var premium = box.new(na, na, na, na
  , bgcolor = color.new(premium_css, 80)
  , border_color = na)
fib1 := 1-fib1
fib2 := 1-fib2
fib3 := 1-fib3
//timeLeft = math.max(top_x, btm_x)
price1 = swingBOS < 0 ? trail_up : trail_dn
price2 = swingBOS < 0 ? trail_dn : trail_up
diff = price2-price1
fib1level = price1+diff*fib1
fib2level = price1+diff*fib2
fib3level = price1+diff*fib3
label.set_xy(eq_lbl, n, avg)
//-----------------------------------------------------------------------------}
//Trend
//-----------------------------------------------------------------------------{
var color trend_css = na
if show_trend
    if style == 'Colored'
         trend_css := candlecolor == 1 ? bull_css : candlecolor == 0 ? purplecolor :
bear_css
    else if style == 'Monochrome'
         trend_css := itrend == 1 ? #b2b5be : #5d606b
barcolor(trend_css)
//-----------------------------------------------------------------------------}
//Alerts
//-----------------------------------------------------------------------------{
//Internal Structure
alertcondition(bull_ibos_alert, 'Internal Bullish BOS', 'Internal Bullish BOS
formed')
alertcondition(bull_ichoch_alert, 'Internal Bullish CHoCH', 'Internal Bullish CHoCH
formed')
//Swing Structure
alertcondition(bull_bos_alert, 'Bullish BOS', 'Internal Bullish BOS formed')
alertcondition(bull_choch_alert, 'Bullish CHoCH', 'Internal Bullish CHoCH formed')
//FVG
alertcondition(bullish_fvg_cnd, 'Bullish FVG', 'Bullish FVG formed')
alertcondition(bearish_fvg_cnd, 'Bearish FVG', 'Bearish FVG formed')
//-----------------------------------------------------------------------------}
tb = table.new(position.top_right, 5, 5, bgcolor = #1e222d , border_color =
#373a46 , border_width = 1 , frame_color = #373a46 , frame_width = 1)
dashboardGreenText =#42bda8
squeezegreent = #0a907a
dashboardRedText = #ee787d
squeezeredt = #ed3544
dashboardGreenBackground = #284444
squeezegreenbg = #1a3a3e
dashboardRedBackground = #49343e
squeezeredbg = #482632
if structureScannerOn
    if barstate.islast
         tb.cell(0, 0, "Structure Scanner (" +
formatTimeframeString(scannerTimeframe) + ')', text_size = size.small, text_color =
#9399a2)
         tb.cell(0, 1, internalText, text_color = iTextColor, bgcolor = iBackground,
text_size = size.small)
         tb.cell(0, 2,swingText, text_color = swingTextColor, bgcolor =
swingBackground, text_size = size.small)