Indicator · Pine Script v5 · On the chart

Bull Vs. Bear Market Intraday Sessions [Kioseff Trading]

by regalouisei· code credited to KioseffTrading

Bull Vs.

View on GitHub

GitHub stars2on the repository
Pine versionv5runs as is
Lines of code646
Settings40inputs
LicenceNone statedfile: MPL-2.0
Last update8 months ago25 Feb 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

646 lines of Pine Script v5 from pinescript/editors_picks/10x-bull-vs-bear-vp-intraday-sessions-kioseff-trading.pine, published under MPL-2.0 (file header). Keep the author's credit and licence lines when you reuse it.

10x-bull-vs-bear-vp-intraday-sessions-kioseff-trading.pine
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © KioseffTrading

//@version=5
indicator("Bull Vs. Bear Market Intraday Sessions [Kioseff Trading]", overlay = true, max_lines_count = 500, max_labels_count = 500, max_boxes_count = 500, max_polylines_count = 100, max_bars_back = 5000)
import RicardoSantos/MathOperator/2
import kaigouthro/hsvColor/15 as kai
import HeWhoMustNotBeNamed/arraymethods/1

timeTrue(string timeRange) => 

    math.sign(time("1", timeRange, "UTC"))
// 
showT1        = input.bool  (defval = true , title = "", group = "Profiles to Show", inline = "T1"), t1 = input.string(defval = "Range 1" , title = "", inline = "T1",  group = "Profiles to Show")
showT2        = input.bool  (defval = true , title = "", group = "Profiles to Show", inline = "T2"), t2 = input.string(defval = "Range 2" , title = "", inline = "T2",  group = "Profiles to Show")
showT3        = input.bool  (defval = true , title = "", group = "Profiles to Show", inline = "T3"), t3 = input.string(defval = "Range 3 ", title = "", inline = "T3",  group = "Profiles to Show")
showT4        = input.bool  (defval = true , title = "", group = "Profiles to Show", inline = "T4"), t4 = input.string(defval = "Range 4" , title = "", inline = "T4",  group = "Profiles to Show")
showT5        = input.bool  (defval = false, title = "", group = "Profiles to Show", inline = "T5"), t5 = input.string(defval = "Range 5" , title = "", inline = "T5",  group = "Profiles to Show")
showT6        = input.bool  (defval = false, title = "", group = "Profiles to Show", inline = "T6"), t6 = input.string(defval = "Range 6" , title = "", inline = "T6",  group = "Profiles to Show")
showT7        = input.bool  (defval = false, title = "", group = "Profiles to Show", inline = "T7"), t7 = input.string(defval = "Range 7 ", title = "", inline = "T7",  group = "Profiles to Show")
showT8        = input.bool  (defval = false, title = "", group = "Profiles to Show", inline = "T8"), t8 = input.string(defval = "Range 8" , title = "", inline = "T8",  group = "Profiles to Show")
showT9        = input.bool  (defval = false, title = "", group = "Profiles to Show", inline = "T9"), t9 = input.string(defval = "Range 9" , title = "", inline = "T9",  group = "Profiles to Show")

T1T           = input.session  ("0000-0600"  ,   title = ""    , inline = "T1", group = "Profiles to Show")
T2T           = input.session  ("0600-1200"  ,   title = ""    , inline = "T2", group = "Profiles to Show")
T3T           = input.session  ("1200-1800"  ,   title = ""    , inline = "T3", group = "Profiles to Show")
T4T           = input.session  ("1800-0000"  ,   title = ""    , inline = "T4", group = "Profiles to Show")
T5T           = input.session  ("0000-0600"  ,   title = ""    , inline = "T5", group = "Profiles to Show")
T6T           = input.session  ("0600-1200"  ,   title = ""    , inline = "T6", group = "Profiles to Show")
T7T           = input.session  ("1200-1800"  ,   title = ""    , inline = "T7", group = "Profiles to Show")
T8T           = input.session  ("1800-0000"  ,   title = ""    , inline = "T8", group = "Profiles to Show")
T9T           = input.session  ("0000-0600"  ,   title = ""    , inline = "T9", group = "Profiles to Show")
showLI        = input.bool     (defval = true,   title = "Live", inline = "LI", group = "Profiles to Show")
LIT           = input.timeframe("1D"         ,   title = ""    , inline = "LI", group = "Profiles to Show")

upColT1       = input.color (defval = #14D990     , title = ""  , group = "Profiles to Show", inline = "T1"), dnColT1       = input.color (defval = #F24968     , title = ""  , group = "Profiles to Show", inline = "T1")
upColT2       = input.color (defval = #14D990     , title = ""  , group = "Profiles to Show", inline = "T2"), dnColT2       = input.color (defval = #F24968     , title = ""  , group = "Profiles to Show", inline = "T2")
upColT3       = input.color (defval = #14D990     , title = ""  , group = "Profiles to Show", inline = "T3"), dnColT3       = input.color (defval = #F24968     , title = ""  , group = "Profiles to Show", inline = "T3")
upColT4       = input.color (defval = #14D990     , title = ""  , group = "Profiles to Show", inline = "T4"), dnColT4       = input.color (defval = #F24968     , title = ""  , group = "Profiles to Show", inline = "T4")
upColT5       = input.color (defval = #14D990     , title = ""  , group = "Profiles to Show", inline = "T5"), dnColT5       = input.color (defval = #F24968     , title = ""  , group = "Profiles to Show", inline = "T5")
upColT6       = input.color (defval = #14D990     , title = ""  , group = "Profiles to Show", inline = "T6"), dnColT6       = input.color (defval = #F24968     , title = ""  , group = "Profiles to Show", inline = "T6")
upColT7       = input.color (defval = #14D990     , title = ""  , group = "Profiles to Show", inline = "T7"), dnColT7       = input.color (defval = #F24968     , title = ""  , group = "Profiles to Show", inline = "T7")
upColT8       = input.color (defval = #14D990     , title = ""  , group = "Profiles to Show", inline = "T8"), dnColT8       = input.color (defval = #F24968     , title = ""  , group = "Profiles to Show", inline = "T8")
upColT9       = input.color (defval = #14D990     , title = ""  , group = "Profiles to Show", inline = "T9"), dnColT9       = input.color (defval = #F24968     , title = ""  , group = "Profiles to Show", inline = "T9")
upColLI       = input.color (defval = color.lime  , title = ""  , group = "Profiles to Show", inline = "LI"), dnColLI       = input.color (defval = color.red   , title = ""  , group = "Profiles to Show", inline = "LI"), atr = ta.atr(14)


boxed         = input.bool  (defval = true, title = "Boxed Sessions")
ROWS          = input.int   (defval = 100, maxval = 2000, minval = 10, step = 10, title = "Profile Rows", group = "Profile Settings")
factor        = input.float (defval = 4, minval = 1.1, step = 0.1, title = "Scaling Factor", group = "Profile Settings")
same          = input.string(defval = "Same Side", title = "VP Plot Type", options = ["Middle", "Same Side"], group = "Profile Settings")

showdel       = input.bool  (defval = false, title = "Show Delta", group = "Delta Settings")
deltaRows     = input.int   (defval = 20, minval = 5, title = "Delta Rows", group = "Delta Settings")
deltaSz       = input.string(defval = "Tiny", title = "Delta Text Size", options = ["Tiny", "Small", "Normal", "Large", "Huge"], group = "Delta Settings")

poc           = input.bool  (defval = false, title = "Show POC", group = "POC Settings", inline = "1")
delet         = input.bool  (defval = false, title = "Delete Violated POCs",  group = "POC Settings", inline = "1")
poctype       = input.string(defval = "Regular POC", title = "POC Type", options = ["Bull & Bear POC", "Regular POC"], group = "POC Settings")
show          = input.int   (defval = 10, title = "POCs To Show", maxval = 500, minval = 1, group = "POC Settings") 
wid           = input.int   (defval = 2, title = "POC Width", group = "POC Settings")
generalPOCcol = input.color (defval = color.yellow, title = "Normal POC Col", group = "POC Settings")
transp3       = input.int   (defval = 25, minval = 0, maxval = 100, group = "POC Settings", title = "POC Line Transparency")



valines       = input.bool  (defval = false, title = "Show VA Lines", inline = "VA", group = "VA Settings"), vacol = input.color(defval = color.white, title = "", inline = "VA", group = "VA Settings")
cumu          = input.float (defval = 70, title = "Value Area %", minval = 5, maxval = 95, group = "VA Settings")
vashow        = input.int   (defval = 20, title = "VA Lines To Show", maxval = 500, minval = 1, group = "VA Settings") 
deletva       = input.bool  (defval = false, title = "Delete Violated VA Lines", group = "VA Settings")
transp        = input.int   (defval = 90, minval = 0, maxval = 100, group = "VA Settings", title = "VA Pofile Fill Transparency")
transp2       = input.int   (defval = 0 , minval = 0, maxval = 100, group = "VA Settings", title = "VA Pofile Line Transparency")
transpv       = input.int   (defval = 95, minval = 0, maxval = 100, title = "NON VA Fill Transparency", group = "NON VA Settings")
transpv2      = input.int   (defval = 70, minval = 0, maxval = 100, title = "NON VA Line Transparency", group = "NON VA Settings")

N             = bar_index

show    := switch poctype 
    
    "Regular POC" => show + 1 
    =>               show * 2

type dataStore

    matrix <float> timeVolMat 
    matrix <float> HLmat
    array  <int>   retArr 
    array  <line>  pocs 
    array  <line>  valine
    array  <label> deltaLabels
    map    <float, float> mappedLevel


type profiles 

    matrix <float> tickLevelsT1
    matrix <float> tickLevelsT2
    matrix <float> tickLevelsT3
    matrix <float> tickLevelsT4
    matrix <float> tickLevelsT5
    matrix <float> tickLevelsT6
    matrix <float> tickLevelsT7
    matrix <float> tickLevelsT8
    matrix <float> tickLevelsT9

var data = dataStore.new(matrix.new<float>(2, 0), matrix.new<float>(2, 0), array.new_int(), array.new_line(), array.new_line()),                                                                                                                                                                       //kioseff
tLevels  = profiles.new( matrix.new<float>(3, ROWS, 0.0), matrix.new<float>(3, ROWS, 0.0),matrix.new<float>(3, ROWS, 0.0),matrix.new<float>(3, ROWS, 0.0), 
                         matrix.new<float>(3, ROWS, 0.0), matrix.new<float>(3, ROWS, 0.0),matrix.new<float>(3, ROWS, 0.0),matrix.new<float>(3, ROWS, 0.0), 
                         matrix.new<float>(3, ROWS, 0.0)) 

determine(a, b) => 

    result = switch same 

        "Same Side"     => a
        "Middle"        => b

determineLive(a, b, live) => 

    result = switch live

        false    => a
        =>          b


method double_binary_search_leftmost(array <float> id, i) =>

    n  = id .binary_search_leftmost  (data.HLmat.get(0, i))
    n1 = id .binary_search_leftmost  (data.HLmat.get(1, i))

    [n, n1]

method double_binary_search_leftmost_delta(array <float> id, top, btm) =>

    n   = id .binary_search_leftmost  (top)
    n1  = id .binary_search_leftmost  (btm)

    [n, n1]

// 
method effSwitch(matrix<float> id, i, x, div, subtract) =>

    switch data.retArr.get(i)

        1  => id.set(1, x, id.get(1, x) + data.timeVolMat.get(1, i - subtract) / div)
        -1 => id.set(2, x, id.get(2, x) + data.timeVolMat.get(1, i - subtract) / div)



method drawPOC(array<line> id, startIndex, upCol, dnCol,  idrow, newRowUp, newRowDn, 
     remove, array<float> timeRow = na, cond1 = false, int enterStart = na) => 
    
    avg = math.round(math.avg(N, startIndex))

    if remove 
        id.flush()

    if poc 

        [start, end] = if not cond1 
            
            switch

                same == "Middle" => [avg, N]
                =>                  [math.max(startIndex, N - 999), N]

        else 

            [math.max(enterStart, N - 999), N + 40]

        if poctype == "Bull & Bear POC"

            for i = 0 to 1
            // 
                [arr, col] = switch  
                // 
                    i == 0 => [newRowUp , upCol] 
                    i == 1 => [newRowDn , dnCol]

                y = math.avg(idrow.get(arr.indexof(arr.max())), idrow.get(math.min(arr.indexof(arr.max()) + 1, arr.size() - 1)))

                id.push(line.new(x1 = start, y1 = y, x2 = end, y2 = y, color = color.new(col, transp3), width = wid))

        else 

            for i = 0 to newRowUp.size() - 1
                newRowUp.set(i, newRowUp.get(i) + newRowDn.get(i))

            y = math.avg(idrow.get(newRowUp.indexof(newRowUp.max())), idrow.get(math.min(newRowUp.indexof(newRowUp.max()) + 1, idrow.size() - 1)))

            id.push(line.new(x1 = start, y1 = y, x2 = end, y2 = y, color = color.new(generalPOCcol, transp3), width = wid))



method setLevels(matrix<float> id, float gety, float gety2) =>

    rows = (gety2 - gety) / (ROWS - 1)

    for i = 0 to ROWS - 1
        id.set(0, i, gety + rows * i)

finalPoints = array.new_float(6), coordsUp = matrix.new<chart.point>(2, 0), coordsDn = matrix.new<chart.point>(2, 0)


method flushMat(matrix<chart.point> id) => 

    if id.columns() > 0 
        for i = 0 to id.columns() - 1
            id.remove_col()
    

method createPoly(matrix<chart.point> id, array<float> timeRow, int add, int getx2, int getx, bool cond, 
                                     array<float> idrow, array<float> lows, array<float> highs, startIndex, 
                                     color upCol, color dnCol, array<polyline> id2) => 

    avg = switch cond 

        false => math.round(math.avg(N, startIndex))
        =>       N + 200


    [finx, finDn, finUp] = if same != "Middle"    

        switch cond 

            false => [startIndex, idrow.min(), idrow.max()]
            =>       [N + 200, lows.min(), highs.max()]

    else 

        switch cond 

            false => [avg, idrow.min(), idrow.max()]
            =>       [N + 100, lows.min(), highs.max()]

    id.add_col(0, 
             array.from(chart.point.from_index(finx, finalPoints.get(4)) ,chart.point.from_index(finx, finalPoints.get(4))))

    id.add_col(id.columns(), 
             array.from(chart.point.from_index(finx, finalPoints.get(5)) ,chart.point.from_index(finx, finalPoints.get(5)))) 

    if coordsDn.columns() > 0
        coordsDn.add_col(0,
                 array.from(chart.point.from_index(finx, finalPoints.first()) ,chart.point.from_index(finx, finalPoints.first())))

        coordsDn.add_col(coordsDn.columns(),
                 array.from(chart.point.from_index(finx, finalPoints.get(1)) ,chart.point.from_index(finx, finalPoints.get(1))))

        id2.push(polyline.new(coordsDn.row(1), fill_color = color.new(dnCol, transpv), line_color  = color.new(dnCol, transpv2), curved = false))
        id2.push(polyline.new(coordsDn.row(0), fill_color = color.new(upCol, transpv), line_color  = color.new(upCol, transpv2), curved = false))

    if coordsUp.columns() > 0

        coordsUp.add_col(0,
                 array.from(chart.point.from_index(finx, finalPoints.get(2)) ,chart.point.from_index(finx, finalPoints.get(2))))

        coordsUp.add_col(coordsUp.columns(),
                 array.from(chart.point.from_index(finx, finalPoints.get(3)) ,chart.point.from_index(finx, finalPoints.get(3))))

        id2.push(polyline.new(coordsUp.row(1), fill_color = color.new(dnCol, transpv), line_color  = color.new(dnCol, transpv2), curved = false))
        id2.push(polyline.new(coordsUp.row(0), fill_color = color.new(upCol, transpv), line_color  = color.new(upCol, transpv2), curved = false))


    id2.push(polyline.new(id.row(1), fill_color = color.new(dnCol, transp), line_color  = color.new(dnCol, transp2), curved = false))
    id2.push(polyline.new(id.row(0), fill_color = color.new(upCol, transp), line_color  = color.new(upCol, transp2), curved = false))

    coordsDn.flushMat()
    coordsUp.flushMat()
    finalPoints.fill(na)

norm(newRowUp, newRowDn, oldMin, oldMax, newRange, i) => 

    calcUp = 1 + ((newRowUp.get(i) - oldMin) / (oldMax - oldMin)) * (newRange - 1)
    calcDn = 1 + ((newRowDn.get(i) - oldMin) / (oldMax - oldMin)) * (newRange - 1)

    [calcUp, calcDn]



method calcDelta(array<float> id, array<float> newRowUp, array<float> newRowDn, float getY, float getY2, int middle, color upCol, color dnCol) => 
 

    if showdel 

        var dsz = switch deltaSz

            "Tiny"   => size.tiny 
            "Small"  => size.small 
            "Normal" => size.normal 
            "Large"  => size.large
            "Huge"   => size.huge

        db           = dataStore.new(mappedLevel = map.new<float, float>(), deltaLabels = array.new_label())
        var lastdb   = dataStore.new(deltaLabels = array.new_label())     
        var liveLab  = array.new_label()

        if lastdb.deltaLabels.size() > 0 
            for i = lastdb.deltaLabels.size() - 1 to 0 
                lastdb.deltaLabels.remove(i).delete()

        if liveLab.size() > 0 
            liveLab.remove(0).delete() 

        newSlice = (math.max(getY, getY2) - math.min(getY, getY2)) / deltaRows

        idx = switch bar_index == last_bar_index

            true => lastdb.deltaLabels
            =>      db.deltaLabels

        for i = 0 to deltaRows - 1
                
            db.mappedLevel.put(i, 0.0)

            btm = math.min(getY, getY2) + (newSlice * i)
            top = math.min(getY, getY2) + (newSlice * (i + 1))

            idx.push(label.new(chart.point.from_index(middle, math.avg(top, btm)),
                             textcolor = color.white, style = label.style_none, color = #00000000, size = dsz))

            [topCol, btmCol] = id.double_binary_search_leftmost_delta(top, btm)

            for x = btmCol to topCol

                db.mappedLevel.put(i, db.mappedLevel.get(i) + (newRowUp.get(x) - newRowDn.get(x)))

        valArr = db.mappedLevel.values(), valArr.sort(order.ascending), array <float> pos = na, array <float> neg = na

        if valArr.last ().over (0)
            pos := valArr.slice(   valArr.binary_search_rightmost(0), valArr.size())
        if valArr.first().under(0)
            neg := valArr.slice(0, valArr.binary_search_leftmost (0))

        for i = 0 to deltaRows - 1

            col = switch math.sign(db.mappedLevel.get(i))

                1  => color.from_gradient(db.mappedLevel.get(i), pos.min(), pos.max(), color.new(upCol, 50), color.new(upCol, 10))
                -1 => color.from_gradient(db.mappedLevel.get(i), neg.max(), neg.min(), color.new(dnCol, 10), color.new(dnCol, 50))
                =>    color.new(color.white, 75)

            idx.get(i).set_textcolor        (col),
            idx.get(i).set_text(str.tostring(db.mappedLevel.get(i), format.volume))

        sumCol = switch math.sign(newRowUp.sum() - newRowDn.sum())

            1  => upCol
            -1 => dnCol 
            =>  color.white


        if N < last_bar_index

            label.new(chart.point.from_index(middle, math.max(getY, getY2) + atr * 4),
                                                  color = #00000000,
                                                  textcolor    = sumCol,
                                                  text         = str.tostring(newRowUp.sum() - newRowDn.sum(), format.volume))
        if N == last_bar_index 

            liveLab.push(label.new(chart.point.from_index(middle, math.max(getY, getY2) + atr * 4),
                                                  color = #00000000,
                                                  textcolor    = sumCol,
                                                  text         = str.tostring(newRowUp.sum() - newRowDn.sum(), format.volume)))




method findValue(array <float> id, id2, id3, start, idrow, id4, remove, manual) =>

    copyArr = array.new_float() 

    for i = 0 to id2.size() - 1
        copyArr.push(id2.get(i) + id3.get(i))

    highest = copyArr.indexof(copyArr.max())

    for i = 1 to id2.size() - 1
    
        slice = id2.slice(math.max(highest - i, 0), math.min(highest + i + 1, id2.size()))

        if slice.sum() / id2.sum() >= cumu / 100
            
            id.set(0, math.max(highest - i, 0))
            id.set(1, math.min(highest + i, id2.size() - 1))
            break

    if valines 

        if remove 

            id4.flush()

        end = switch remove 

            false => N 
            =>       manual

        id4.push(
                     line.new(chart.point.from_index(start,   idrow.get(int(id.first()))),
                              chart.point.from_index(end,     idrow.get(int(id.first()))), 
                              color = vacol, xloc = xloc.bar_index))
        id4.push(
                     line.new(chart.point.from_index(start,   idrow.get(int(math.min(id.get(1) + 1, idrow.size() - 1)))),
                              chart.point.from_index(end,     idrow.get(int(math.min(id.get(1) + 1, idrow.size() - 1)))),
                              color = vacol, xloc = xloc.bar_index))
// 

method addPoints(matrix<chart.point> id, newXUp, newXDn, startIndex, avg, i, idrow, subtract, live) => 

    adjDn = switch same 

        "Same Side" => newXUp + (newXDn - (startIndex + 1))
        =>             newXDn

    id.add_col(id.columns(), array.from( chart.point.from_index(math.round(newXUp), idrow.get(i)),
                                         chart.point.from_index(math.round(adjDn), idrow.get(i) )))

    id.add_col(id.columns(), array.from( chart.point.from_index(math.round(newXUp), nz(idrow.get(i + 1))),
                                         chart.point.from_index(math.round(adjDn), nz(idrow.get(i + 1)))))

    [newAvgU, newAvgD] = switch same 

        "Middle" => [avg - subtract, avg + subtract]
        =>          [startIndex + subtract, startIndex + subtract]

    id.add_col(id.columns(), array.from( chart.point.from_index(newAvgU, nz(idrow.get(i + 1))),
                                         chart.point.from_index(math.round(newXUp), nz(idrow.get(i + 1)))))

method setCoordsHistory(matrix<chart.point> id, newRowUp, newRowDn, oldMin, oldMax, newRange, timeRow, getx, getx2, idrow, 
             startIndex, subtract, live = false, id2, remove, manual) =>

    avg = math.round(math.avg(N, startIndex)), detValue = array.from(-1, int(9e9))

    start = switch same 

        "Same Side" => startIndex
        =>             avg

    detValue.findValue(newRowUp, newRowDn, start, idrow, id2, remove, manual)

    for i = 0 to newRowUp.size() - 2

        [calcUp, calcDn] = norm(newRowUp, newRowDn, oldMin, oldMax, newRange, i)

        newSwitchUp = switch same

            "Middle" => avg - calcUp
            =>          determineLive(startIndex + calcUp, startIndex - calcUp, live)

        newXUp = switch same 
            
            "Middle" =>  math.min(newSwitchUp, avg - 1)
            =>           determineLive(math.max(newSwitchUp, startIndex + 1), math.min(startIndex - 1, newSwitchUp), live)

        newSwitchDn =  determine(
                                 determineLive(startIndex + calcDn, startIndex - calcDn, live),
                                 avg + calcDn)

        newXDn      =  determine(
                                 determineLive(math.max(newSwitchDn, startIndex + 1), math.min(newSwitchDn, startIndex - 1), live),
                                 math.max(newSwitchDn, avg + 1))


        switch 

            i < detValue.first() =>  coordsDn.addPoints(newXUp, newXDn, startIndex, avg, i, idrow, subtract, live), 
                                     finalPoints.set(0, math.min(nz(finalPoints.first(), 9e9), idrow.get(i))),
                                     finalPoints.set(1, math.max(nz(finalPoints.get (1), -1), idrow.get(i + 1)))

            i > detValue.get(1)  =>  coordsUp.addPoints(newXUp, newXDn, startIndex, avg, i, idrow, subtract, live), 
                                     finalPoints.set(2, math.min(nz(finalPoints.get(2), 9e9), idrow.get(i))),
                                     finalPoints.set(3, math.max(nz(finalPoints.get(3), -1), idrow.get(i + 1)))

            =>                       id      .addPoints(newXUp, newXDn, startIndex, avg, i, idrow, subtract, live), 
                                     finalPoints.set(4, math.min(nz(finalPoints.get(4), 9e9), idrow.get(i))),
                                     finalPoints.set(5, math.max(nz(finalPoints.get(5), -1) , idrow.get(i + 1)))

data.timeVolMat.add_col(0, array.from(time, volume))
data.HLmat     .add_col(0, array.from(high, low))
data.retArr    .unshift(int(math.sign(close - open)))


method update(matrix<float> id, string timeRange, bool cond, color upCol, color dnCol, string sess) => 
    
    tim = timeTrue(timeRange), tim1 = tim[1]

    if cond

        change = na(tim) and tim1.equal(1)
        var startIndex = 0 

        if tim.equal(1) and na(tim1)
            startIndex := N

        diff = N - startIndex

        if not barstate.islast
        
            if change 

                timeRow = data.timeVolMat.row(0)

                highsArr = data.HLmat.row(0).slice(1, diff)
                lowsArr  = data.HLmat.row(1).slice(1, diff)

                getx2 = N, getx = N - startIndex
                gety = lowsArr.min(), gety2 = highsArr.max()


                if boxed 
                    box.new(startIndex, gety2, N - 1, gety, bgcolor = color.new(color.blue, 95), border_color = color.white, 
                         border_style = line.style_dashed)
                    label.new(math.round(math.avg(startIndex, N - 1)), gety2, text = sess, textcolor = kai.hsv_gradient(0, -1, 1, upCol, dnCol), 
                         color = #00000000, size = size.small)


                id.setLevels(gety, gety2)
                idrow = id.row(0)

                for i = 1 to diff

                    [l1, l2] = idrow.double_binary_search_leftmost(i)

                    div = math.abs(l1 - l2) + 1

                    for x = l1 to l2 

                        id.effSwitch(i, x, div, 0)

                newRange = math.floor((N - startIndex) / factor)
                newRowUp = id.row(1), newRowDn = id.row(2)
                oldMin   = math.min(newRowUp.min(), newRowDn.min())  
                oldMax   = math.max(newRowUp.max(), newRowDn.max())



                coordinates = matrix.new<chart.point>(2, 0), placeHolder = array.new<polyline>()
    
                coordinates.setCoordsHistory(newRowUp, newRowDn, oldMin, oldMax, newRange, timeRow, getx, getx2, idrow, startIndex, 1, false, data.valine, false, int(na))
                coordinates.createPoly(timeRow, diff, getx2, getx, false,  idrow, na, na, startIndex, upCol, dnCol, placeHolder)
                idrow      .calcDelta(newRowUp, newRowDn, gety, gety2, math.round(math.avg(N, startIndex)), upCol, dnCol)
                data.pocs  .drawPOC(startIndex, upCol, dnCol, idrow, newRowUp, newRowDn, false, timeRow)

realtime () => 

    if showLI

        var timArr = array.new_int(1), var tBack = array.new_line()
// 
        if timeframe.change(LIT)
            timArr.set(0, last_bar_index - N - 1)
            tBack.flush()
            tBack.push(line.new(chart.point.now(high + syminfo.mintick), chart.point.now(low), xloc = xloc.bar_time, color = #00000000, extend = extend.both))
// 

        if barstate.islast

            timArr.set(0, timArr.first() + 1)

            if tBack.size() > 1
                tBack.pop().delete()
           
            tBack.push(line.new(chart.point.now(high + syminfo.mintick), chart.point.now(low), xloc = xloc.bar_time, color = #00000000, extend = extend.both))

            linefill.all.flush()
            linefill.new(tBack.first(), tBack.last(), color.new(#6929F2, 95))

            var pocsLive    = dataStore.new(pocs = array.new_line(), valine = array.new_line())
            var coordinates = matrix.new<chart.point>(2, 0), var livePoly = array.new<polyline>()

            if coordinates.columns() > 0 

                for i = 0 to coordinates.columns() - 1
                    coordinates.remove_col()

            if livePoly.size() > 0 
                for i = 0 to livePoly.size() - 1
                    livePoly.shift().delete()


            startIndex = timArr.first()
            timeRow    = data.timeVolMat.row(0)

            highs = data.HLmat.row(0).slice(0, startIndex + 1)
            lows  = data.HLmat.row(1).slice(0, startIndex + 1)
            getx2 = N, getx = startIndex

            newLevelsMat = matrix.new<float>(3, ROWS, 0.0)
            newLevelsMat.setLevels(lows.min(), highs.max())

            levelsArr = newLevelsMat.row(0)

            for i = 0 to startIndex

                [l1, l2] = levelsArr.double_binary_search_leftmost(i)

                div = math.abs(l1 - l2) + 1

                for x = l1 to l2 

                    newLevelsMat.effSwitch(i, x, div, 0)

            newRange   = 80
            newRowUp   = newLevelsMat.row(1), newRowDn = newLevelsMat.row(2)
            oldMin     = math.min(newRowUp.min(), newRowDn.min())  
            oldMax     = math.max(newRowUp.max(), newRowDn.max())
            coordinates.setCoordsHistory(newRowUp, newRowDn, oldMin, oldMax, newRange, timeRow, getx, getx2, levelsArr, 
                                 N + 200, 0, true, pocsLive.valine, true, N - startIndex)
            coordinates.createPoly(timeRow, na, na, na, true, na, lows, highs, N + 200, upColLI, dnColLI, livePoly)
            levelsArr  .calcDelta(newRowUp, newRowDn, lows.min(), highs.max(), N + 225, upColLI, dnColLI)
            pocsLive.pocs.drawPOC(startIndex, upColLI, dnColLI, levelsArr, newRowUp, newRowDn, true, timeRow, true, N - timArr.first())

method keyLevelsUpdate(array<line> id, showtyp, deletyp) => 

    if id.size() > 0 
        for i = 0 to id.size() - 1

            if high < id.get(i).get_y1() or low > id.get(i).get_y1()
                if id.get(i).get_x2() == N - 1 
                    id.get(i).set_x2(N)

            else if deletyp 
                id.get(i).delete()
            
            if deletyp
                if id.get(i).get_x2() != N 
                    id.get(i).delete()

    if barstate.islast 

        if id.size() > showtyp
            for i = 0 to math.max(id.size() - showtyp - 1 , 0)
                id.get(i).delete()  


tLevels.tickLevelsT1.update(T1T, showT1, upColT1, dnColT1, t1), tLevels.tickLevelsT2.update(T2T, showT2, upColT2, dnColT2, t2) 
tLevels.tickLevelsT4.update(T4T, showT4, upColT4, dnColT4, t4), tLevels.tickLevelsT3.update(T3T, showT3, upColT3, dnColT3, t3) 

tLevels.tickLevelsT5.update(T5T, showT5, upColT5, dnColT5, t5), tLevels.tickLevelsT6.update(T6T, showT6, upColT6, dnColT6, t6) 
tLevels.tickLevelsT4.update(T7T, showT7, upColT7, dnColT7, t7), tLevels.tickLevelsT3.update(T8T, showT8, upColT8, dnColT8, t8), 

                                 tLevels.tickLevelsT9.update(T9T, showT9, upColT9, dnColT9, t9)


realtime()
data.pocs.keyLevelsUpdate(show, delet), data.valine.keyLevelsUpdate(vashow, deletva)

Overview

Bear Market Intraday Sessions partitions the trading day into multiple custom time intervals to analyze session-specific volume and market behavior. Plotted directly on the main price chart, the indicator tracks buying and selling dynamics across up to nine user-defined intraday sessions, such as standard six-hour blocks, alongside a configurable live session profile. Inputs allow traders to toggle individual ranges on or off, edit specific session start and end times in UTC, and adjust visual color themes. Profile calculations update dynamically on active bars.

Details

Published by

regalouisei on GitHub

Code credit

KioseffTrading, as written in the script's header

Type

Indicator, Pine Script v5

Draws

On the price chart

Category

Sessions & time, Volume, Support & resistance

Markets

Any symbol

Timeframes

M1-M5, M15-H1

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
showT1booltrueshowT1
t1stringRange 1t1
showT2booltrueshowT2
t2stringRange 2t2
showT3booltrueshowT3
t3stringRange 3 t3
showT4booltrueshowT4
t4stringRange 4t4
showT5boolfalseshowT5
t5stringRange 5t5
showT6boolfalseshowT6
t6stringRange 6t6
Show all 40 settings
SettingTypeDefaultVariable
showT7boolfalseshowT7
t7stringRange 7 t7
showT8boolfalseshowT8
t8stringRange 8t8
showT9boolfalseshowT9
t9stringRange 9t9
T1Tsession0000-0600T1T
T2Tsession0600-1200T2T
T3Tsession1200-1800T3T
T4Tsession1800-0000T4T
T5Tsession0000-0600T5T
T6Tsession0600-1200T6T
T7Tsession1200-1800T7T
T8Tsession1800-0000T8T
T9Tsession0000-0600T9T
LivebooltrueshowLI
LITtimeframe1DLIT
upColT1color#14D990upColT1
dnColT1color#F24968dnColT1
upColT2color#14D990upColT2
dnColT2color#F24968dnColT2
upColT3color#14D990upColT3
dnColT3color#F24968dnColT3
upColT4color#14D990upColT4
dnColT4color#F24968dnColT4
upColT5color#14D990upColT5
dnColT5color#F24968dnColT5
upColT6color#14D990upColT6
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

VP

by dearvn
257 stars

This indicator calculates and plots a session-based volume profile directly on the price chart. It maps volume distribution across price levels, highlighting key structural reference points including the Point of Control, Value Area High, and Value Area Low. C

Indicator v5 VolumeSupport & resistance
Updated 6 weeks ago · None stated GitHub repository of VP

Midnight VWAP

by TradersPost
218 stars

The Midnight VWAP indicator calculates and overlays two distinct Volume Weighted Average Price (VWAP) lines on the price chart based on customizable session timeframes. It tracks an overnight or pre-market session alongside regular trading hours, resetting cal

Indicator v6 Moving averagesSessions & time
Updated 3 months ago · None stated GitHub repository of Midnight VWAP

Moon Dev GEX Arrows

by moondevonyt
92 stars

This overlay indicator plots option strike walls and an optional session VWAP on the price chart for SPY or ES. It spaces major strikes by the selected instrument, draws a set number of strikes on each side, and marks wall-trap and sweep events after a cooldow

Indicator v5 Support & resistanceSessions & time
Updated 8 weeks ago · Custom licence GitHub repository of Moon Dev GEX Arrows

This overlay indicator draws a volume profile for a chosen trading session directly on the price chart. It plots the point of control, value area high and low, an optional value area box, a live zone, and a session box with labels. Users select Tokyo, London,

Indicator v5 Sessions & timeVolume
Updated 7 weeks ago · None stated GitHub repository of Sessions & VP with prev session VP & daily/weekly opens

LoD Intraday Entry

by ChartsLector
41 stars

This overlay indicator marks the current day's low and a suggested entry zone a fraction of daily ATR below that low. It compares daily volume with a volume moving average, plots daily SMA and EMA distance, and draws an optional ATR-width price cloud. Labels c

Indicator v6 Support & resistanceVolatility & bands
Updated 2 days ago · None stated GitHub repository of LoD Intraday Entry

RS: Market Profile

by agejevasv
12 stars

This indicator plots a Market Profile on the price chart using time-price opportunity letters or symbols. It marks the point of control, a configurable value area, and the initial balance, and it can highlight a volume-profile point of control and session VWAP

Indicator v5 VolumeSupport & resistance
Updated 2 years ago · None stated GitHub repository of RS: Market Profile

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