Indicator · Pine Script v6 · On the chart

Orderflow Break Tape Earlier Version

by Blendoxius

An earlier release of the swing structure overlay that marks change of character, break of structure and liquidity events on the price chart.

View on GitHub

GitHub stars1on the repository
Pine versionv6current
Lines of code1,212
Settings40inputs
LicenceNone statedfile: MPL-2.0
Last update10 months ago9 Dec 2025

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

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

ThisPineScriptOderflowV23.txt
// This Pine Script® code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Blendoxius

//@version=6
indicator("ORDERFLOW BREAK TAPE v23", overlay=true, max_lines_count=500, max_labels_count=500)

// ════════════════════════════════════════════════════════════════════════════════
// SECTION 1: MAIN SETTINGS
// ════════════════════════════════════════════════════════════════════════════════

swingLookback = input. int(5, "Swing Lookback", minval=1, maxval=50, group="1.  Main Settings")
maxSwings = input.int(50, "Max Swings", minval=10, maxval=500, group="1.  Main Settings")
avgLookback = input. int(100, "Average Lookback", minval=10, maxval=500, group="1.  Main Settings")

enableChoch = input.bool(true, "Enable CHoCH", group="1. Main Settings")
enableBos = input.bool(true, "Enable BOS", group="1. Main Settings")
enableLiq = input.bool(true, "Enable LIQ", group="1. Main Settings")

// ════════════════════════════════════════════════════════════════════════════════
// SECTION 2: VOLUME STRENGTH FILTER
// ════════════════════════════════════════════════════════════════════════════════

enableVolumeFilter = input.bool(true, "Enable Volume Filter", group="2. Volume Filter")
volumeCompareMode = input.string("Custom Bars", "Compare Mode", options=["Custom Bars", "Tape Average"], group="2. Volume Filter")
volumeCompareBars = input.int(3, "Compare to Last X Bars", minval=1, maxval=50, group="2.  Volume Filter")
volumeStrengthThreshold = input.float(1.0, "Strength Threshold", minval=0.5, maxval=5.0, step=0.1, group="2. Volume Filter")
applyFilterToChoch = input.bool(true, "Apply to CHoCH", group="2. Volume Filter")
applyFilterToBos = input. bool(true, "Apply to BOS", group="2. Volume Filter")
showWeakChoch = input.bool(true, "Show Weak CHoCH", group="2. Volume Filter")
showWeakBos = input.bool(true, "Show Weak BOS", group="2. Volume Filter")

// ════════════════════════════════════════════════════════════════════════════════
// SECTION 3: SWING HIGH - ACTIVE
// ════════════════════════════════════════════════════════════════════════════════

swingHighActiveColor = input.color(color. rgb(244,67,54), "Active Color", group="3.  Swing High Active", inline="sha")
swingHighActiveWidth = input.int(1, "Width", minval=1, maxval=10, group="3.  Swing High Active", inline="sha")
swingHighActiveStyle = input.string("solid", "Style", options=["solid", "dashed", "dotted"], group="3. Swing High Active", inline="sha")

// ════════════════════════════════════════════════════════════════════════════════
// SECTION 4: SWING HIGH - BROKEN STRONG
// ════════════════════════════════════════════════════════════════════════════════

swingHighBrokenStrongColor = input. color(color.rgb(0,255,0), "Strong Color", group="4. Swing High Broken Strong", inline="shbs")
swingHighBrokenStrongWidth = input. int(2, "Width", minval=1, maxval=10, group="4. Swing High Broken Strong", inline="shbs")
swingHighBrokenStrongStyle = input.string("solid", "Style", options=["solid", "dashed", "dotted"], group="4. Swing High Broken Strong", inline="shbs")

// ════════════════════════════════════════════════════════════════════════════════
// SECTION 5: SWING HIGH - BROKEN WEAK
// ════════════════════════════════════════════════════════════════════════════════

swingHighBrokenWeakColor = input.color(color. rgb(100,100,100), "Weak Color", group="5. Swing High Broken Weak", inline="shbw")
swingHighBrokenWeakWidth = input.int(1, "Width", minval=1, maxval=10, group="5. Swing High Broken Weak", inline="shbw")
swingHighBrokenWeakStyle = input. string("dotted", "Style", options=["solid", "dashed", "dotted"], group="5. Swing High Broken Weak", inline="shbw")

// ════════════════════════════════════════════════════════════════════════════════
// SECTION 6: SWING HIGH - TOUCHED (LIQ)
// ════════════════════════════════════════════════════════════════════════════════

swingHighTouchedColor = input.color(color.rgb(255,193,7), "Touched Color", group="6. Swing High Touched", inline="sht")
swingHighTouchedWidth = input.int(1, "Width", minval=1, maxval=10, group="6.  Swing High Touched", inline="sht")
swingHighTouchedStyle = input.string("dashed", "Style", options=["solid", "dashed", "dotted"], group="6. Swing High Touched", inline="sht")

// ════════════════════════════════════════════════════════════════════════════════
// SECTION 7: SWING LOW - ACTIVE
// ════════════════════════════════════════════════════════════════════════════════

swingLowActiveColor = input.color(color.rgb(76,175,80), "Active Color", group="7. Swing Low Active", inline="sla")
swingLowActiveWidth = input.int(1, "Width", minval=1, maxval=10, group="7. Swing Low Active", inline="sla")
swingLowActiveStyle = input.string("solid", "Style", options=["solid", "dashed", "dotted"], group="7. Swing Low Active", inline="sla")

// ════════════════════════════════════════════════════════════════════════════════
// SECTION 8: SWING LOW - BROKEN STRONG
// ════════════════════════════════════════════════════════════════════════════════

swingLowBrokenStrongColor = input.color(color.rgb(255,0,0), "Strong Color", group="8. Swing Low Broken Strong", inline="slbs")
swingLowBrokenStrongWidth = input.int(2, "Width", minval=1, maxval=10, group="8. Swing Low Broken Strong", inline="slbs")
swingLowBrokenStrongStyle = input.string("solid", "Style", options=["solid", "dashed", "dotted"], group="8. Swing Low Broken Strong", inline="slbs")

// ════════════════════════════════════════════════════════════════════════════════
// SECTION 9: SWING LOW - BROKEN WEAK
// ════════════════════════════════════════════════════════════════════════════════

swingLowBrokenWeakColor = input.color(color.rgb(100,100,100), "Weak Color", group="9.  Swing Low Broken Weak", inline="slbw")
swingLowBrokenWeakWidth = input.int(1, "Width", minval=1, maxval=10, group="9. Swing Low Broken Weak", inline="slbw")
swingLowBrokenWeakStyle = input.string("dotted", "Style", options=["solid", "dashed", "dotted"], group="9. Swing Low Broken Weak", inline="slbw")

// ════════════════════════════════════════════════════════════════════════════════
// SECTION 10: SWING LOW - TOUCHED (LIQ)
// ════════════════════════════════════════════════════════════════════════════════

swingLowTouchedColor = input.color(color. rgb(255,193,7), "Touched Color", group="10. Swing Low Touched", inline="slt")
swingLowTouchedWidth = input. int(1, "Width", minval=1, maxval=10, group="10. Swing Low Touched", inline="slt")
swingLowTouchedStyle = input.string("dashed", "Style", options=["solid", "dashed", "dotted"], group="10.  Swing Low Touched", inline="slt")

// ════════════════════════════════════════════════════════════════════════════════
// SECTION 11: CHOCH LABEL SETTINGS
// ════════════════════════════════════════════════════════════════════════════════

showChochLabels = input.bool(true, "Show CHoCH Labels", group="11. CHoCH Labels")
chochUpStrongColor = input.color(color.rgb(0,255,255), "Up Strong", group="11. CHoCH Labels", inline="chu")
chochUpWeakColor = input. color(color.rgb(0,120,120), "Up Weak", group="11. CHoCH Labels", inline="chu")
chochDownStrongColor = input.color(color. rgb(255,165,0), "Down Strong", group="11. CHoCH Labels", inline="chd")
chochDownWeakColor = input.color(color.rgb(150,100,0), "Down Weak", group="11.  CHoCH Labels", inline="chd")
chochLabelSizeStr = input.string("small", "Label Size", options=["tiny", "small", "normal", "large"], group="11. CHoCH Labels")
chochLabelPosition = input.string("Break Point", "Label Position", options=["Break Point", "Center of Line"], group="11. CHoCH Labels")

// ════════════════════════════════════════════════════════════════════════════════
// SECTION 12: BOS LABEL SETTINGS
// ════════════════════════════════════════════════════════════════════════════════

showBosLabels = input.bool(true, "Show BOS Labels", group="12. BOS Labels")
bosUpStrongColor = input.color(color.rgb(0,255,0), "Up Strong", group="12. BOS Labels", inline="bosu")
bosUpWeakColor = input.color(color. rgb(0,120,0), "Up Weak", group="12. BOS Labels", inline="bosu")
bosDownStrongColor = input.color(color.rgb(255,0,0), "Down Strong", group="12. BOS Labels", inline="bosd")
bosDownWeakColor = input. color(color.rgb(120,0,0), "Down Weak", group="12. BOS Labels", inline="bosd")
bosLabelSizeStr = input.string("tiny", "Label Size", options=["tiny", "small", "normal", "large"], group="12. BOS Labels")
bosLabelPosition = input. string("Break Point", "Label Position", options=["Break Point", "Center of Line"], group="12. BOS Labels")

// ════════════════════════════════════════════════════════════════════════════════
// SECTION 13: LIQ LABEL SETTINGS
// ════════════════════════════════════════════════════════════════════════════════

showLiqLabels = input.bool(true, "Show LIQ Labels", group="13. LIQ Labels")
liqUpColor = input.color(color.rgb(255,235,59), "Up Color", group="13.  LIQ Labels", inline="liq")
liqDownColor = input.color(color.rgb(255,235,59), "Down Color", group="13. LIQ Labels", inline="liq")
liqLabelSizeStr = input.string("tiny", "Label Size", options=["tiny", "small", "normal", "large"], group="13. LIQ Labels")

// ════════════════════════════════════════════════════════════════════════════════
// SECTION 14: TABLE AND SCROLL SETTINGS
// ════════════════════════════════════════════════════════════════════════════════

showTable = input.bool(true, "Show Table", group="14. Table & Scroll")
showDiffColumn = input.bool(true, "Show DIFF Column", group="14. Table & Scroll", tooltip="Shows Spread vs Volume difference in %")
tablePosition = input.string("Top Right", "Table Position", options=["Top Left", "Top Center", "Top Right", "Middle Left", "Middle Center", "Middle Right", "Bottom Left", "Bottom Center", "Bottom Right"], group="14. Table & Scroll")
tableTextSize = input.string("small", "Text Size", options=["tiny", "small", "normal", "large"], group="14. Table & Scroll")
visibleRows = input. int(15, "Visible Rows", minval=5, maxval=50, group="14.  Table & Scroll")
scrollOffset = input.int(0, "Scroll Offset", minval=0, maxval=500, group="14.  Table & Scroll", tooltip="0 = newest first, increase to scroll back")
tableFilterMode = input.string("All Candles", "Filter Mode", options=["All Candles", "Events Only", "CHoCH Only", "BOS Only", "LIQ Only"], group="14. Table & Scroll")

// ════════════════════════════════════════════════════════════════════════════════
// SECTION 15: TABLE COLORS
// ════════════════════════════════════════════════════════════════════════════════

tableBgColor = input.color(color. rgb(18,18,18), "Background", group="15. Table Colors")
headerBgColor = input.color(color. rgb(38,38,38), "Header Background", group="15. Table Colors")
footerBgColor = input.color(color.rgb(28,28,28), "Footer Background", group="15. Table Colors")
textColor = input.color(color.rgb(220,220,220), "Text Color", group="15. Table Colors")

// ════════════════════════════════════════════════════════════════════════════════
// SECTION 16: SPREAD WINDOW SETTINGS
// ════════════════════════════════════════════════════════════════════════════════

showSpreadWindow = input. bool(true, "Show Spread Window", group="16.  Spread Window")
spreadWindowPosition = input. string("Bottom Right", "Position", options=["Top Left", "Top Center", "Top Right", "Middle Left", "Middle Center", "Middle Right", "Bottom Left", "Bottom Center", "Bottom Right"], group="16. Spread Window")
spreadWindowSize = input.string("small", "Size", options=["tiny", "small", "normal", "large"], group="16. Spread Window")
showSpreadAsPercent = input.bool(true, "Show as Percent", group="16. Spread Window")
spreadColorNormal = input.color(color.rgb(76,175,80), "Normal Color", group="16. Spread Window")
spreadColorHigh = input.color(color.rgb(255,82,82), "High Volatility Color", group="16. Spread Window")
spreadColorCompression = input.color(color.rgb(33,150,243), "Compression Color", group="16.  Spread Window")
spreadHighThreshold = input.float(1.5, "High Threshold", minval=1.0, maxval=5.0, step=0.1, group="16.  Spread Window")
spreadLowThreshold = input.float(0.5, "Compression Threshold", minval=0.1, maxval=1.0, step=0.1, group="16. Spread Window")

// ════════════════════════════════════════════════════════════════════════════════
// SECTION 17: ROLLING WINDOWS
// ════════════════════════════════════════════════════════════════════════════════

showRollingWindows = input.bool(true, "Show Rolling Windows", group="17. Rolling Windows")
window1 = input. int(5, "Window 1", minval=0, maxval=500, group="17.  Rolling Windows", inline="w1")
window2 = input.int(10, "Window 2", minval=0, maxval=500, group="17. Rolling Windows", inline="w1")
window3 = input.int(20, "Window 3", minval=0, maxval=500, group="17.  Rolling Windows", inline="w2")
window4 = input.int(50, "Window 4", minval=0, maxval=500, group="17.  Rolling Windows", inline="w2")
window5 = input. int(0, "Window 5", minval=0, maxval=500, group="17.  Rolling Windows", inline="w3")
window6 = input. int(0, "Window 6", minval=0, maxval=500, group="17. Rolling Windows", inline="w3")

// ════════════════════════════════════════════════════════════════════════════════
// SECTION 18: LEVEL THRESHOLDS
// ════════════════════════════════════════════════════════════════════════════════

sprdLvl1 = input.float(0.5, "Spread Level 1 (Empty)", minval=0.1, maxval=2.0, step=0.1, group="18. Level Thresholds")
sprdLvl2 = input. float(1.0, "Spread Level 2 (Normal)", minval=0.5, maxval=3.0, step=0.1, group="18. Level Thresholds")
sprdLvl3 = input. float(1.5, "Spread Level 3 (Move)", minval=1.0, maxval=4.0, step=0.1, group="18. Level Thresholds")
sprdLvl4 = input. float(2.0, "Spread Level 4 (Power)", minval=1.5, maxval=5.0, step=0.1, group="18. Level Thresholds")

volLvl1 = input.float(0.5, "Volume Level 1 (Empty)", minval=0.1, maxval=2.0, step=0.1, group="18. Level Thresholds")
volLvl2 = input.float(1.0, "Volume Level 2 (Normal)", minval=0.5, maxval=3.0, step=0.1, group="18. Level Thresholds")
volLvl3 = input.float(1.5, "Volume Level 3 (Move)", minval=1.0, maxval=4.0, step=0.1, group="18. Level Thresholds")
volLvl4 = input.float(2.0, "Volume Level 4 (Power)", minval=1.5, maxval=5.0, step=0.1, group="18. Level Thresholds")

// ════════════════════════════════════════════════════════════════════════════════
// SECTION 19: CONTROL THRESHOLDS
// ════════════════════════════════════════════════════════════════════════════════

ctrlWeakAbove = input.float(60.0, "Control Weak: Above %", minval=50.0, maxval=75.0, step=5.0, group="19. Control Thresholds")
ctrlStrongAbove = input.float(80.0, "Control Strong: Above %", minval=70.0, maxval=90.0, step=5.0, group="19. Control Thresholds")
ctrlMaxAbove = input. float(80.0, "Control Max (Maru): Above %", minval=75.0, maxval=95.0, step=5.0, group="19.  Control Thresholds")

// ════════════════════════════════════════════════════════════════════════════════
// SECTION 20: FLOW COLORS
// ════════════════════════════════════════════════════════════════════════════════

colorAbsorb = input.color(color.rgb(33,150,243), "Absorb Color", group="20.  Flow Colors")
colorManip = input.color(color.rgb(255,235,59), "Manipulation Color", group="20. Flow Colors")
colorBull = input.color(color.rgb(76,175,80), "Bull Color", group="20. Flow Colors")
colorBear = input.color(color.rgb(255,82,82), "Bear Color", group="20. Flow Colors")
colorHigh = input.color(color.rgb(255,82,82), "High Color", group="20. Flow Colors")
colorMid = input.color(color.rgb(255,167,38), "Mid Color", group="20. Flow Colors")
colorNorm = input.color(color.rgb(76,175,80), "Normal Color", group="20. Flow Colors")
colorGray = input.color(color.rgb(128,128,128), "Gray Color", group="20. Flow Colors")

// ════════════════════════════════════════════════════════════════════════════════
// HELPER FUNCTIONS
// ════════════════════════════════════════════════════════════════════════════════

getLineStyle(string s) =>
    s == "solid" ? line.style_solid : s == "dashed" ? line.style_dashed : line.style_dotted

getLabelSize(string s) =>
    s == "tiny" ? size.tiny : s == "small" ? size.small : s == "large" ? size.large : size.normal

getTextSize() =>
    tableTextSize == "tiny" ? size.tiny : tableTextSize == "small" ? size.small : tableTextSize == "large" ? size.large : size.normal

getTablePosition() =>
    tablePosition == "Top Left" ? position.top_left : tablePosition == "Top Center" ? position. top_center : tablePosition == "Top Right" ? position.top_right : tablePosition == "Middle Left" ? position.middle_left : tablePosition == "Middle Center" ? position.middle_center : tablePosition == "Middle Right" ?  position.middle_right : tablePosition == "Bottom Left" ? position.bottom_left : tablePosition == "Bottom Center" ? position.bottom_center : position.bottom_right

getSpreadWindowPosition() =>
    spreadWindowPosition == "Top Left" ? position.top_left : spreadWindowPosition == "Top Center" ? position.top_center : spreadWindowPosition == "Top Right" ? position.top_right : spreadWindowPosition == "Middle Left" ? position.middle_left : spreadWindowPosition == "Middle Center" ? position.middle_center : spreadWindowPosition == "Middle Right" ? position.middle_right : spreadWindowPosition == "Bottom Left" ? position.bottom_left : spreadWindowPosition == "Bottom Center" ? position.bottom_center : position.bottom_right

getSpreadWindowSize() =>
    spreadWindowSize == "tiny" ? size.tiny : spreadWindowSize == "small" ? size.small : spreadWindowSize == "large" ? size.large : size.normal

formatTime(t) =>
    str.tostring(hour(t, "Europe/Berlin"), "00") + ":" + str.tostring(minute(t, "Europe/Berlin"), "00") 

formatPct(p) =>
    str.tostring(p, "#.#") + "%"

dimColor(c, dim) =>
    dim ? color.new(c, 60) : c

shouldShowRow(chB, chS, bosB, bosS, liqB, liqS) =>
    if tableFilterMode == "All Candles"
        true
    else if tableFilterMode == "Events Only"
        chB > 0 or chS > 0 or bosB > 0 or bosS > 0 or liqB > 0 or liqS > 0
    else if tableFilterMode == "CHoCH Only"
        chB > 0 or chS > 0
    else if tableFilterMode == "BOS Only"
        bosB > 0 or bosS > 0
    else if tableFilterMode == "LIQ Only"
        liqB > 0 or liqS > 0
    else
        true

// ════════════════════════════════════════════════════════════════════════════════
// LEVEL FUNCTIONS
// ════════════════════════════════════════════════════════════════════════════════

getSprdLevel(mult) =>
    if mult < sprdLvl1
        0
    else if mult < sprdLvl2
        1
    else if mult < sprdLvl3
        2
    else if mult < sprdLvl4
        3
    else
        4

getVolLevel(mult) =>
    if mult < volLvl1
        0
    else if mult < volLvl2
        1
    else if mult < volLvl3
        2
    else if mult < volLvl4
        3
    else
        4

getSprdLabel(mult) =>
    int lvl = getSprdLevel(mult)
    lvl == 0 ? "EMPTY" : lvl == 1 ? "NORM" : lvl == 2 ? "MOVE" : lvl == 3 ? "POWER" : "EXTRM"

getVolLabel(mult) =>
    int lvl = getVolLevel(mult)
    lvl == 0 ?  "EMPTY" : lvl == 1 ? "NORM" : lvl == 2 ? "MOVE" : lvl == 3 ? "POWER" : "EXTRM"

getSprdColor(mult) =>
    int lvl = getSprdLevel(mult)
    lvl == 0 ? colorGray : lvl == 1 ? colorNorm : lvl == 2 ? colorMid : lvl == 3 ? colorHigh : colorHigh

getVolColor(mult) =>
    int lvl = getVolLevel(mult)
    lvl == 0 ?  colorGray : lvl == 1 ? colorNorm : lvl == 2 ? colorMid : lvl == 3 ? colorHigh : colorHigh

// ════════════════════════════════════════════════════════════════════════════════
// CANDLE ANATOMY FUNCTIONS
// ════════════════════════════════════════════════════════════════════════════════

calcCandleAnatomy() =>
    float candleRange = high - low
    float bodySize = math.abs(close - open)
    float upperWick = high - math.max(close, open)
    float lowerWick = math.min(close, open) - low
    float upperWickPct = candleRange > 0 ? (upperWick / candleRange) * 100 : 0
    float bodyPct = candleRange > 0 ? (bodySize / candleRange) * 100 : 0
    float lowerWickPct = candleRange > 0 ? (lowerWick / candleRange) * 100 : 0
    bool isBull = close >= open
    [upperWickPct, bodyPct, lowerWickPct, isBull]

getWickColor(pct) =>
    pct >= 50 ? colorHigh : pct >= 30 ? colorMid : pct >= 15 ? colorNorm : colorGray

getBodyColor(pct, isBull) =>
    if pct >= 80
        isBull ? colorBull : colorBear
    else if pct >= 60
        isBull ? colorBull : colorBear
    else if pct >= 40
        colorMid
    else
        colorGray

// ════════════════════════════════════════════════════════════════════════════════
// FLOW FUNCTIONS
// ════════════════════════════════════════════════════════════════════════════════

getFlowType(sprdMult, volMult) =>
    int sprdLevel = getSprdLevel(sprdMult)
    int volLevel = getVolLevel(volMult)
    int diff = volLevel - sprdLevel
    if diff >= 2
        "ABSORB++"
    else if diff == 1
        "ABSORB+"
    else if diff == 0
        "NORMAL"
    else if diff == -1
        "MANIP+"
    else
        "MANIP++"

getFlowColor(sprdMult, volMult) =>
    int sprdLevel = getSprdLevel(sprdMult)
    int volLevel = getVolLevel(volMult)
    int diff = volLevel - sprdLevel
    if diff >= 2
        colorAbsorb
    else if diff == 1
        color. new(colorAbsorb, 40)
    else if diff == 0
        colorNorm
    else if diff == -1
        color.new(colorManip, 40)
    else
        colorManip

// ════════════════════════════════════════════════════════════════════════════════
// DIFF FUNCTIONS
// ════════════════════════════════════════════════════════════════════════════════

getDiffValue(sprdMult, volMult) =>
    float diff = volMult - sprdMult
    float diffPct = (diff / math.max(sprdMult, 0.01)) * 100
    diffPct

getDiffLabel(sprdMult, volMult) =>
    float diffPct = getDiffValue(sprdMult, volMult)
    string prefix = diffPct >= 0 ? "+" : ""
    prefix + str.tostring(diffPct, "#.#") + "%"

getDiffColor(sprdMult, volMult) =>
    float diffPct = getDiffValue(sprdMult, volMult)
    if diffPct > 100
        colorAbsorb
    else if diffPct > 50
        color.new(colorAbsorb, 30)
    else if diffPct > 0
        color.new(colorAbsorb, 60)
    else if diffPct > -50
        color. new(colorManip, 60)
    else if diffPct > -100
        color. new(colorManip, 30)
    else
        colorManip

// ════════════════════════════════════════════════════════════════════════════════
// CANDLE TYPE FUNCTIONS (MIT REJECTION LOGIK)
// ════════════════════════════════════════════════════════════════════════════════

getCandleType(upperWickPct, bodyPct, lowerWickPct, isBull) =>
    string candleType = ""
    float bullControl = bodyPct + lowerWickPct
    float bearControl = bodyPct + upperWickPct
    bool isUpperRejection = upperWickPct > bodyPct and upperWickPct > lowerWickPct
    bool isLowerRejection = lowerWickPct > bodyPct and lowerWickPct > upperWickPct
    
    if isUpperRejection
        if bearControl >= ctrlMaxAbove
            candleType := "BIG REJ DN"
        else if bearControl >= ctrlWeakAbove
            candleType := "REJ DN"
        else
            candleType := "NEUTRAL"
    else if isLowerRejection
        if bullControl >= ctrlMaxAbove
            candleType := "BIG REJ UP"
        else if bullControl >= ctrlWeakAbove
            candleType := "REJ UP"
        else
            candleType := "NEUTRAL"
    else
        if isBull
            if bodyPct >= ctrlMaxAbove
                candleType := "MARU"
            else if bullControl >= ctrlStrongAbove
                candleType := "STRONG"
            else if bullControl >= ctrlWeakAbove
                candleType := "STD"
            else
                candleType := "NEUTRAL"
        else
            if bodyPct >= ctrlMaxAbove
                candleType := "MARU"
            else if bearControl >= ctrlStrongAbove
                candleType := "STRONG"
            else if bearControl >= ctrlWeakAbove
                candleType := "STD"
            else
                candleType := "NEUTRAL"
    candleType

getCandleTypeColor(candleType) =>
    if candleType == "MARU" or candleType == "BIG REJ DN" or candleType == "BIG REJ UP"
        colorHigh
    else if candleType == "STRONG"
        colorMid
    else if candleType == "STD" or candleType == "REJ DN" or candleType == "REJ UP"
        colorNorm
    else
        colorGray

// ════════════════════════════════════════════════════════════════════════════════
// CONTROL FUNCTIONS
// ════════════════════════════════════════════════════════════════════════════════

getControlLabel(upperWickPct, bodyPct, lowerWickPct, isBull) =>
    float bullControl = bodyPct + lowerWickPct
    float bearControl = bodyPct + upperWickPct
    bool isUpperRejection = upperWickPct > bodyPct and upperWickPct > lowerWickPct
    bool isLowerRejection = lowerWickPct > bodyPct and lowerWickPct > upperWickPct
    
    string ctrl = "NONE"
    
    if isUpperRejection
        if bearControl >= ctrlMaxAbove
            ctrl := "SELL++"
        else if bearControl >= ctrlStrongAbove
            ctrl := "SELL+"
        else if bearControl >= ctrlWeakAbove
            ctrl := "SELL"
        else
            ctrl := "NONE"
    else if isLowerRejection
        if bullControl >= ctrlMaxAbove
            ctrl := "BUY++"
        else if bullControl >= ctrlStrongAbove
            ctrl := "BUY+"
        else if bullControl >= ctrlWeakAbove
            ctrl := "BUY"
        else
            ctrl := "NONE"
    else if isBull
        if bodyPct >= ctrlMaxAbove
            ctrl := "BUY++"
        else if bullControl >= ctrlStrongAbove
            ctrl := "BUY+"
        else if bullControl >= ctrlWeakAbove
            ctrl := "BUY"
        else
            ctrl := "NONE"
    else
        if bodyPct >= ctrlMaxAbove
            ctrl := "SELL++"
        else if bearControl >= ctrlStrongAbove
            ctrl := "SELL+"
        else if bearControl >= ctrlWeakAbove
            ctrl := "SELL"
        else
            ctrl := "NONE"
    ctrl

getControlColor(ctrl) =>
    if ctrl == "BUY++" or ctrl == "BUY+" or ctrl == "BUY"
        colorBull
    else if ctrl == "SELL++" or ctrl == "SELL+" or ctrl == "SELL"
        colorBear
    else
        colorGray

getControlBuyScore(ctrl) =>
    ctrl == "BUY++" ? 3 : ctrl == "BUY+" ?  2 : ctrl == "BUY" ? 1 : 0

getControlSellScore(ctrl) =>
    ctrl == "SELL++" ? 3 : ctrl == "SELL+" ? 2 : ctrl == "SELL" ?  1 : 0

// ════════════════════════════════════════════════════════════════════════════════
// VOLUME STRENGTH FUNCTION
// ════════════════════════════════════════════════════════════════════════════════

calculateVolumeStrength(startBar, endBar) =>
    float moveVolume = 0.0
    float compareVolume = 0.0
    int barsInMove = endBar - startBar
    
    if barsInMove > 0
        for i = 0 to barsInMove - 1
            moveVolume += volume[i]
        moveVolume := moveVolume / barsInMove
    
    if volumeCompareMode == "Custom Bars"
        for i = 0 to volumeCompareBars - 1
            compareVolume += volume[barsInMove + i]
        compareVolume := compareVolume / volumeCompareBars
    else
        compareVolume := ta.sma(volume, avgLookback)
    
    bool isStrong = compareVolume > 0 ?  (moveVolume / compareVolume) >= volumeStrengthThreshold : true
    [moveVolume, compareVolume, isStrong]

// ════════════════════════════════════════════════════════════════════════════════
// END OF PART 1
// ════════════════════════════════════════════════════════════════════════════════
// ════════════════════════════════════════════════════════════════════════════════
// AVERAGE CALCULATIONS
// ════════════════════════════════════════════════════════════════════════════════

float avgSpread = ta.sma(high - low, avgLookback)
float avgVolume = ta.sma(volume, avgLookback)
float currentSpread = high - low
float currentSpreadPct = close > 0 ? (currentSpread / close) * 100 : 0
float avgSpreadPct = ta.sma(currentSpreadPct, avgLookback)
float curSprdMult = avgSpread > 0 ? currentSpread / avgSpread : 1
float curVolMult = avgVolume > 0 ? volume / avgVolume : 1

[curUpperWickPct, curBodyPct, curLowerWickPct, curIsBull] = calcCandleAnatomy()
string curCandleType = getCandleType(curUpperWickPct, curBodyPct, curLowerWickPct, curIsBull)
string curFlowType = getFlowType(curSprdMult, curVolMult)
string curControl = getControlLabel(curUpperWickPct, curBodyPct, curLowerWickPct, curIsBull)

// ════════════════════════════════════════════════════════════════════════════════
// SPREAD WINDOW CALCULATIONS
// ════════════════════════════════════════════════════════════════════════════════

float currentSpreadVal = showSpreadAsPercent ? currentSpreadPct : currentSpread
float avgSpreadWindow = showSpreadAsPercent ? avgSpreadPct : avgSpread
float spreadRatio = avgSpreadWindow > 0 ? currentSpreadVal / avgSpreadWindow : 1
string volatilityRegime = spreadRatio >= spreadHighThreshold ? "HIGH VOLA" : spreadRatio <= spreadLowThreshold ? "LOW VOLA" : "NORMAL"
color spreadThresholdColor = spreadRatio >= spreadHighThreshold ? spreadColorHigh : spreadRatio <= spreadLowThreshold ? spreadColorCompression : spreadColorNormal

// ════════════════════════════════════════════════════════════════════════════════
// SWING TRACKING ARRAYS
// ════════════════════════════════════════════════════════════════════════════════

var array<float> swingHighVals = array. new_float(0)
var array<int> swingHighBars = array.new_int(0)
var array<bool> swingHighActive = array.new_bool(0)
var array<bool> swingHighTouched = array.new_bool(0)
var array<line> swingHighLines = array.new_line(0)

var array<float> swingLowVals = array.new_float(0)
var array<int> swingLowBars = array.new_int(0)
var array<bool> swingLowActive = array.new_bool(0)
var array<bool> swingLowTouched = array.new_bool(0)
var array<line> swingLowLines = array.new_line(0)

var int currentTrend = 0

// ════════════════════════════════════════════════════════════════════════════════
// SWING DETECTION
// ════════════════════════════════════════════════════════════════════════════════

bool enoughBars = bar_index >= swingLookback * 2
float highestInWindow = ta.highest(high, swingLookback * 2 + 1)
float lowestInWindow = ta.lowest(low, swingLookback * 2 + 1)
bool isSwingHigh = enoughBars and high[swingLookback] == highestInWindow
bool isSwingLow = enoughBars and low[swingLookback] == lowestInWindow

if isSwingHigh
    float val = high[swingLookback]
    int bar = bar_index - swingLookback
    line l = line.new(bar, val, bar_index, val, color=swingHighActiveColor, width=swingHighActiveWidth, style=getLineStyle(swingHighActiveStyle))
    array.push(swingHighVals, val)
    array. push(swingHighBars, bar)
    array.push(swingHighActive, true)
    array.push(swingHighTouched, false)
    array.push(swingHighLines, l)
    if array.size(swingHighVals) > maxSwings
        line.delete(array. shift(swingHighLines))
        array.shift(swingHighVals)
        array.shift(swingHighBars)
        array.shift(swingHighActive)
        array.shift(swingHighTouched)

if isSwingLow
    float val = low[swingLookback]
    int bar = bar_index - swingLookback
    line l = line.new(bar, val, bar_index, val, color=swingLowActiveColor, width=swingLowActiveWidth, style=getLineStyle(swingLowActiveStyle))
    array.push(swingLowVals, val)
    array.push(swingLowBars, bar)
    array.push(swingLowActive, true)
    array. push(swingLowTouched, false)
    array.push(swingLowLines, l)
    if array.size(swingLowVals) > maxSwings
        line.delete(array.shift(swingLowLines))
        array.shift(swingLowVals)
        array.shift(swingLowBars)
        array. shift(swingLowActive)
        array.shift(swingLowTouched)

// ════════════════════════════════════════════════════════════════════════════════
// EVENT DETECTION
// ════════════════════════════════════════════════════════════════════════════════

int curChochBull = 0
int curChochBear = 0
int curBosBull = 0
int curBosBear = 0
int curLiqBull = 0
int curLiqBear = 0
bool hasAnyEvent = false
bool curChochBullStrong = false
bool curChochBearStrong = false
bool curBosBullStrong = false
bool curBosBearStrong = false

// Check Swing High Breaks
if array.size(swingHighVals) > 0
    for i = 0 to array. size(swingHighVals) - 1
        if array. get(swingHighActive, i)
            float y = array.get(swingHighVals, i)
            int x1 = array.get(swingHighBars, i)
            line l = array.get(swingHighLines, i)
            bool closeAbove = close > y
            bool highAbove = high > y
            bool broken = closeAbove and highAbove
            
            if broken
                array.set(swingHighActive, i, false)
                
                bool isStrong = true
                if enableVolumeFilter
                    [moveVol, compareVol, volStrong] = calculateVolumeStrength(x1, bar_index)
                    isStrong := volStrong
                
                bool isChoch = currentTrend == -1
                
                if isChoch and enableChoch
                    bool applyFilter = applyFilterToChoch ?  isStrong : true
                    curChochBull += 1
                    curChochBullStrong := isStrong
                    hasAnyEvent := true
                    
                    if not na(l)
                        if isStrong
                            line.set_color(l, swingHighBrokenStrongColor)
                            line.set_width(l, swingHighBrokenStrongWidth)
                            line.set_style(l, getLineStyle(swingHighBrokenStrongStyle))
                        else
                            line.set_color(l, swingHighBrokenWeakColor)
                            line.set_width(l, swingHighBrokenWeakWidth)
                            line.set_style(l, getLineStyle(swingHighBrokenWeakStyle))
                        line.set_x2(l, bar_index)
                    
                    if showChochLabels and (isStrong or showWeakChoch)
                        color labelColor = isStrong ? chochUpStrongColor : chochUpWeakColor
                        string labelText = isStrong ? "CHoCH" : "choch"
                        int labelBar = chochLabelPosition == "Center of Line" ? int((x1 + bar_index) / 2) : bar_index
                        label.new(labelBar, y, labelText, color=color. new(color.white, 100), textcolor=labelColor, style=label.style_none, yloc=yloc.price, size=getLabelSize(chochLabelSizeStr))
                    
                    currentTrend := 1
                
                else if enableBos
                    curBosBull += 1
                    curBosBullStrong := isStrong
                    hasAnyEvent := true
                    
                    if not na(l)
                        if isStrong
                            line.set_color(l, swingHighBrokenStrongColor)
                            line.set_width(l, swingHighBrokenStrongWidth)
                            line.set_style(l, getLineStyle(swingHighBrokenStrongStyle))
                        else
                            line.set_color(l, swingHighBrokenWeakColor)
                            line.set_width(l, swingHighBrokenWeakWidth)
                            line.set_style(l, getLineStyle(swingHighBrokenWeakStyle))
                        line.set_x2(l, bar_index)
                    
                    if showBosLabels and (isStrong or showWeakBos)
                        color labelColor = isStrong ? bosUpStrongColor : bosUpWeakColor
                        string labelText = isStrong ? "BOS" : "bos"
                        int labelBar = bosLabelPosition == "Center of Line" ?  int((x1 + bar_index) / 2) : bar_index
                        label.new(labelBar, y, labelText, color=color.new(color.white, 100), textcolor=labelColor, style=label.style_none, yloc=yloc.price, size=getLabelSize(bosLabelSizeStr))
                    
                    currentTrend := 1
            
            else if highAbove and not closeAbove and enableLiq
                if not array.get(swingHighTouched, i)
                    array.set(swingHighTouched, i, true)
                    curLiqBull += 1
                    hasAnyEvent := true
                    
                    if showLiqLabels
                        label.new(bar_index, y, "LIQ", color=color.new(color. white, 100), textcolor=liqUpColor, style=label. style_none, yloc=yloc. price, size=getLabelSize(liqLabelSizeStr))
                    
                    if not na(l)
                        line.set_color(l, swingHighTouchedColor)
                        line.set_width(l, swingHighTouchedWidth)
                        line. set_style(l, getLineStyle(swingHighTouchedStyle))
                
                if not na(l)
                    line.set_x2(l, bar_index)
            
            else
                if not na(l)
                    line.set_x2(l, bar_index)

// Check Swing Low Breaks
if array.size(swingLowVals) > 0
    for i = 0 to array.size(swingLowVals) - 1
        if array.get(swingLowActive, i)
            float y = array.get(swingLowVals, i)
            int x1 = array.get(swingLowBars, i)
            line l = array.get(swingLowLines, i)
            bool closeBelow = close < y
            bool lowBelow = low < y
            bool broken = closeBelow and lowBelow
            
            if broken
                array.set(swingLowActive, i, false)
                
                bool isStrong = true
                if enableVolumeFilter
                    [moveVol, compareVol, volStrong] = calculateVolumeStrength(x1, bar_index)
                    isStrong := volStrong
                
                bool isChoch = currentTrend == 1
                
                if isChoch and enableChoch
                    bool applyFilter = applyFilterToChoch ? isStrong : true
                    curChochBear += 1
                    curChochBearStrong := isStrong
                    hasAnyEvent := true
                    
                    if not na(l)
                        if isStrong
                            line.set_color(l, swingLowBrokenStrongColor)
                            line.set_width(l, swingLowBrokenStrongWidth)
                            line.set_style(l, getLineStyle(swingLowBrokenStrongStyle))
                        else
                            line.set_color(l, swingLowBrokenWeakColor)
                            line. set_width(l, swingLowBrokenWeakWidth)
                            line.set_style(l, getLineStyle(swingLowBrokenWeakStyle))
                        line.set_x2(l, bar_index)
                    
                    if showChochLabels and (isStrong or showWeakChoch)
                        color labelColor = isStrong ? chochDownStrongColor : chochDownWeakColor
                        string labelText = isStrong ? "CHoCH" : "choch"
                        int labelBar = chochLabelPosition == "Center of Line" ?  int((x1 + bar_index) / 2) : bar_index
                        label.new(labelBar, y, labelText, color=color.new(color.white, 100), textcolor=labelColor, style=label.style_none, yloc=yloc.price, size=getLabelSize(chochLabelSizeStr))
                    
                    currentTrend := -1
                
                else if enableBos
                    curBosBear += 1
                    curBosBearStrong := isStrong
                    hasAnyEvent := true
                    
                    if not na(l)
                        if isStrong
                            line. set_color(l, swingLowBrokenStrongColor)
                            line.set_width(l, swingLowBrokenStrongWidth)
                            line.set_style(l, getLineStyle(swingLowBrokenStrongStyle))
                        else
                            line.set_color(l, swingLowBrokenWeakColor)
                            line.set_width(l, swingLowBrokenWeakWidth)
                            line.set_style(l, getLineStyle(swingLowBrokenWeakStyle))
                        line.set_x2(l, bar_index)
                    
                    if showBosLabels and (isStrong or showWeakBos)
                        color labelColor = isStrong ?  bosDownStrongColor : bosDownWeakColor
                        string labelText = isStrong ? "BOS" : "bos"
                        int labelBar = bosLabelPosition == "Center of Line" ? int((x1 + bar_index) / 2) : bar_index
                        label.new(labelBar, y, labelText, color=color.new(color. white, 100), textcolor=labelColor, style=label. style_none, yloc=yloc. price, size=getLabelSize(bosLabelSizeStr))
                    
                    currentTrend := -1
            
            else if lowBelow and not closeBelow and enableLiq
                if not array.get(swingLowTouched, i)
                    array.set(swingLowTouched, i, true)
                    curLiqBear += 1
                    hasAnyEvent := true
                    
                    if showLiqLabels
                        label. new(bar_index, y, "LIQ", color=color.new(color.white, 100), textcolor=liqDownColor, style=label.style_none, yloc=yloc.price, size=getLabelSize(liqLabelSizeStr))
                    
                    if not na(l)
                        line.set_color(l, swingLowTouchedColor)
                        line.set_width(l, swingLowTouchedWidth)
                        line.set_style(l, getLineStyle(swingLowTouchedStyle))
                
                if not na(l)
                    line.set_x2(l, bar_index)
            
            else
                if not na(l)
                    line.set_x2(l, bar_index)

// ════════════════════════════════════════════════════════════════════════════════
// EVENT STORAGE ARRAYS
// ════════════════════════════════════════════════════════════════════════════════

var array<int> evtTime = array.new_int(0)
var array<int> evtChochBull = array. new_int(0)
var array<int> evtChochBear = array.new_int(0)
var array<int> evtBosBull = array.new_int(0)
var array<int> evtBosBear = array.new_int(0)
var array<int> evtLiqBull = array.new_int(0)
var array<int> evtLiqBear = array.new_int(0)
var array<float> evtSprdMult = array. new_float(0)
var array<float> evtVolMult = array. new_float(0)
var array<float> evtUpperWickPct = array.new_float(0)
var array<float> evtBodyPct = array. new_float(0)
var array<float> evtLowerWickPct = array.new_float(0)
var array<bool> evtIsBull = array. new_bool(0)
var array<string> evtCandleType = array. new_string(0)
var array<string> evtFlowType = array. new_string(0)
var array<string> evtControl = array.new_string(0)

if barstate.ishistory or barstate.isconfirmed
    array. unshift(evtTime, time)
    array. unshift(evtChochBull, curChochBull)
    array.unshift(evtChochBear, curChochBear)
    array.unshift(evtBosBull, curBosBull)
    array.unshift(evtBosBear, curBosBear)
    array. unshift(evtLiqBull, curLiqBull)
    array. unshift(evtLiqBear, curLiqBear)
    array. unshift(evtSprdMult, curSprdMult)
    array. unshift(evtVolMult, curVolMult)
    array.unshift(evtUpperWickPct, curUpperWickPct)
    array. unshift(evtBodyPct, curBodyPct)
    array.unshift(evtLowerWickPct, curLowerWickPct)
    array.unshift(evtIsBull, curIsBull)
    array. unshift(evtCandleType, curCandleType)
    array. unshift(evtFlowType, curFlowType)
    array.unshift(evtControl, curControl)

int maxArraySize = math.max(avgLookback, 5000)
if array.size(evtTime) > maxArraySize
    array.pop(evtTime)
    array.pop(evtChochBull)
    array.pop(evtChochBear)
    array. pop(evtBosBull)
    array.pop(evtBosBear)
    array.pop(evtLiqBull)
    array.pop(evtLiqBear)
    array. pop(evtSprdMult)
    array.pop(evtVolMult)
    array. pop(evtUpperWickPct)
    array.pop(evtBodyPct)
    array.pop(evtLowerWickPct)
    array.pop(evtIsBull)
    array.pop(evtCandleType)
    array.pop(evtFlowType)
    array.pop(evtControl)

// ════════════════════════════════════════════════════════════════════════════════
// ROLLING WINDOW STATS FUNCTION
// ════════════════════════════════════════════════════════════════════════════════

calcWindowStats(windowSize) =>
    int chB = 0
    int chS = 0
    int bosB = 0
    int bosS = 0
    int liqB = 0
    int liqS = 0
    int buyScore = 0
    int sellScore = 0
    int evtCount = math.min(array.size(evtChochBull), windowSize)
    if evtCount > 0
        for i = 0 to evtCount - 1
            chB += array.get(evtChochBull, i)
            chS += array.get(evtChochBear, i)
            bosB += array. get(evtBosBull, i)
            bosS += array.get(evtBosBear, i)
            liqB += array. get(evtLiqBull, i)
            liqS += array.get(evtLiqBear, i)
            string ctrl = array.get(evtControl, i)
            buyScore += getControlBuyScore(ctrl)
            sellScore += getControlSellScore(ctrl)
    [chB, chS, bosB, bosS, liqB, liqS, buyScore, sellScore]

// ════════════════════════════════════════════════════════════════════════════════
// END OF PART 2
// ════════════════════════════════════════════════════════════════════════════════
// ════════════════════════════════════════════════════════════════════════════════
// SPREAD WINDOW TABLE
// ════════════════════════════════════════════════════════════════════════════════

var table spreadTable = table.new(getSpreadWindowPosition(), 2, 12, bgcolor=color.rgb(18,18,18), border_width=1, border_color=color. new(color.gray, 50))

if showSpreadWindow and barstate.islast
    swSize = getSpreadWindowSize()
    table.cell(spreadTable, 0, 0, "SPREAD", bgcolor=color.rgb(38,38,38), text_color=color. white, text_size=swSize)
    table.cell(spreadTable, 1, 0, curIsBull ? "BULL" : "BEAR", bgcolor=curIsBull ? colorBull : colorBear, text_color=color.white, text_size=swSize)
    table.cell(spreadTable, 0, 1, "Current:", text_color=color. gray, text_size=swSize, bgcolor=color.rgb(28,28,28))
    table.cell(spreadTable, 1, 1, str. tostring(currentSpreadVal, "#. ###") + (showSpreadAsPercent ? "%" : ""), bgcolor=spreadThresholdColor, text_color=color.white, text_size=swSize)
    table.cell(spreadTable, 0, 2, "Mean:", text_color=color.gray, text_size=swSize, bgcolor=color. rgb(28,28,28))
    table.cell(spreadTable, 1, 2, str. tostring(avgSpreadWindow, "#.###") + (showSpreadAsPercent ? "%" : ""), bgcolor=color.rgb(50,50,50), text_color=color.white, text_size=swSize)
    float spreadMult = avgSpreadWindow > 0 ? currentSpreadVal / avgSpreadWindow : 1
    table. cell(spreadTable, 0, 3, "Mult:", text_color=color.gray, text_size=swSize, bgcolor=color.rgb(28,28,28))
    table.cell(spreadTable, 1, 3, str.tostring(spreadMult, "#.##") + "x", bgcolor=spreadThresholdColor, text_color=color.white, text_size=swSize)
    table.cell(spreadTable, 0, 4, "Regime:", text_color=color.gray, text_size=swSize, bgcolor=color. rgb(28,28,28))
    color regimeColor = volatilityRegime == "HIGH VOLA" ? spreadColorHigh : volatilityRegime == "LOW VOLA" ? spreadColorCompression : spreadColorNormal
    table. cell(spreadTable, 1, 4, volatilityRegime, bgcolor=regimeColor, text_color=color.white, text_size=swSize)
    table. cell(spreadTable, 0, 5, "-------", text_color=color.gray, text_size=swSize, bgcolor=color. rgb(28,28,28))
    table.cell(spreadTable, 1, 5, "-------", text_color=color.gray, text_size=swSize, bgcolor=color. rgb(28,28,28))
    table.cell(spreadTable, 0, 6, "Vol Mode:", text_color=color.gray, text_size=swSize, bgcolor=color. rgb(28,28,28))
    string volModeText = volumeCompareMode == "Custom Bars" ? str.tostring(volumeCompareBars) + " bars" : "Tape Avg"
    table. cell(spreadTable, 1, 6, volModeText, text_color=colorNorm, text_size=swSize, bgcolor=color.rgb(28,28,28))
    table.cell(spreadTable, 0, 7, "Vol Thresh:", text_color=color.gray, text_size=swSize, bgcolor=color. rgb(28,28,28))
    table.cell(spreadTable, 1, 7, str. tostring(volumeStrengthThreshold, "#.#") + "x", text_color=colorNorm, text_size=swSize, bgcolor=color.rgb(28,28,28))
    table.cell(spreadTable, 0, 8, "-------", text_color=color.gray, text_size=swSize, bgcolor=color. rgb(28,28,28))
    table.cell(spreadTable, 1, 8, "-------", text_color=color.gray, text_size=swSize, bgcolor=color. rgb(28,28,28))
    table.cell(spreadTable, 0, 9, "DIFF:", text_color=color.gray, text_size=swSize, bgcolor=color. rgb(28,28,28))
    table.cell(spreadTable, 1, 9, getDiffLabel(curSprdMult, curVolMult), text_color=getDiffColor(curSprdMult, curVolMult), text_size=swSize, bgcolor=color. rgb(28,28,28))

// ════════════════════════════════════════════════════════════════════════════════
// MAIN TABLE
// ════════════════════════════════════════════════════════════════════════════════

int tableColumns = showDiffColumn ? 14 : 13
var table tbl = table.new(getTablePosition(), tableColumns, 85, bgcolor=tableBgColor, border_width=1, border_color=color.new(color. gray, 80))

if showTable and barstate.islast
    tSize = getTextSize()
    int evtCount = array.size(evtTime)
    int currentRow = 0
    int effectiveOffset = math.min(scrollOffset, math.max(0, evtCount - visibleRows))
    int mergeEnd = showDiffColumn ? 12 : 11
    
    // Header
    string titleText = "ORDERFLOW BREAK TAPE v23"
    string filterText = tableFilterMode != "All Candles" ? " [" + tableFilterMode + "]" : ""
    string settingsText = "SW:" + str.tostring(swingLookback) + " AVG:" + str. tostring(avgLookback) + filterText
    
    table.cell(tbl, 0, currentRow, titleText, bgcolor=headerBgColor, text_color=textColor, text_size=tSize, text_halign=text. align_left)
    table.merge_cells(tbl, 0, currentRow, 5, currentRow)
    table.cell(tbl, 6, currentRow, settingsText, bgcolor=headerBgColor, text_color=colorGray, text_size=tSize, text_halign=text.align_right)
    table.merge_cells(tbl, 6, currentRow, mergeEnd, currentRow)
    currentRow += 1
    
    // Rolling Windows
    if showRollingWindows
        windowSizes = array.from(window1, window2, window3, window4, window5, window6)
        for idx = 0 to 5
            int winSize = array.get(windowSizes, idx)
            if winSize > 0
                [chB, chS, bosB, bosS, liqB, liqS, buyScore, sellScore] = calcWindowStats(winSize)
                string winLabel = str.tostring(winSize)
                string bullText = "UP CH:" + str.tostring(chB) + " BOS:" + str.tostring(bosB) + " LIQ:" + str. tostring(liqB)
                string bearText = "DN CH:" + str. tostring(chS) + " BOS:" + str.tostring(bosS) + " LIQ:" + str.tostring(liqS)
                string ctrlText = "BUY:+" + str.tostring(buyScore) + " | SELL:+" + str.tostring(sellScore)
                int totalBull = chB + bosB + liqB
                int totalBear = chS + bosS + liqS
                color winColor = totalBull > totalBear ? colorBull : totalBear > totalBull ? colorBear : colorGray
                color ctrlColor = buyScore > sellScore ?  colorBull : sellScore > buyScore ? colorBear : colorGray
                table.cell(tbl, 0, currentRow, winLabel, bgcolor=color.new(winColor, 85), text_color=winColor, text_size=tSize, text_halign=text.align_center)
                table. cell(tbl, 1, currentRow, bullText, bgcolor=color.new(colorBull, 90), text_color=colorBull, text_size=tSize, text_halign=text.align_left)
                table. merge_cells(tbl, 1, currentRow, 4, currentRow)
                table.cell(tbl, 5, currentRow, bearText, bgcolor=color.new(colorBear, 90), text_color=colorBear, text_size=tSize, text_halign=text.align_left)
                table. merge_cells(tbl, 5, currentRow, 8, currentRow)
                table.cell(tbl, 9, currentRow, ctrlText, bgcolor=color. new(ctrlColor, 85), text_color=ctrlColor, text_size=tSize, text_halign=text.align_center)
                table.merge_cells(tbl, 9, currentRow, mergeEnd, currentRow)
                currentRow += 1
    
    // Column Headers - DIFF zwischen SPRD und VOL
    table.cell(tbl, 0, currentRow, "TIME", bgcolor=headerBgColor, text_color=textColor, text_size=tSize)
    table.cell(tbl, 1, currentRow, "CH", bgcolor=headerBgColor, text_color=textColor, text_size=tSize)
    table.cell(tbl, 2, currentRow, "BOS", bgcolor=headerBgColor, text_color=textColor, text_size=tSize)
    table.cell(tbl, 3, currentRow, "LIQ", bgcolor=headerBgColor, text_color=textColor, text_size=tSize)
    table.cell(tbl, 4, currentRow, "SPRD", bgcolor=headerBgColor, text_color=textColor, text_size=tSize)
    if showDiffColumn
        table.cell(tbl, 5, currentRow, "DIFF", bgcolor=headerBgColor, text_color=textColor, text_size=tSize)
        table.cell(tbl, 6, currentRow, "VOL", bgcolor=headerBgColor, text_color=textColor, text_size=tSize)
        table.cell(tbl, 7, currentRow, "H/WK", bgcolor=headerBgColor, text_color=textColor, text_size=tSize)
        table.cell(tbl, 8, currentRow, "BODY", bgcolor=headerBgColor, text_color=textColor, text_size=tSize)
        table.cell(tbl, 9, currentRow, "L/WK", bgcolor=headerBgColor, text_color=textColor, text_size=tSize)
        table.cell(tbl, 10, currentRow, "FLOW", bgcolor=headerBgColor, text_color=textColor, text_size=tSize)
        table.cell(tbl, 11, currentRow, "TYPE", bgcolor=headerBgColor, text_color=textColor, text_size=tSize)
        table.cell(tbl, 12, currentRow, "CTRL", bgcolor=headerBgColor, text_color=textColor, text_size=tSize)
    else
        table.cell(tbl, 5, currentRow, "VOL", bgcolor=headerBgColor, text_color=textColor, text_size=tSize)
        table.cell(tbl, 6, currentRow, "H/WK", bgcolor=headerBgColor, text_color=textColor, text_size=tSize)
        table.cell(tbl, 7, currentRow, "BODY", bgcolor=headerBgColor, text_color=textColor, text_size=tSize)
        table.cell(tbl, 8, currentRow, "L/WK", bgcolor=headerBgColor, text_color=textColor, text_size=tSize)
        table.cell(tbl, 9, currentRow, "FLOW", bgcolor=headerBgColor, text_color=textColor, text_size=tSize)
        table.cell(tbl, 10, currentRow, "TYPE", bgcolor=headerBgColor, text_color=textColor, text_size=tSize)
        table. cell(tbl, 11, currentRow, "CTRL", bgcolor=headerBgColor, text_color=textColor, text_size=tSize)
    currentRow += 1
    
    // Live Row
    if effectiveOffset == 0 and barstate. isrealtime
        string chTextLive = ""
        if curChochBull > 0 and curChochBear > 0
            chTextLive := str.tostring(curChochBull) + "U " + str.tostring(curChochBear) + "D"
        else if curChochBull > 0
            chTextLive := str.tostring(curChochBull) + "U"
        else if curChochBear > 0
            chTextLive := str.tostring(curChochBear) + "D"
        color chColorLive = curChochBull > 0 and curChochBear > 0 ?  colorMid : curChochBull > 0 ?  chochUpStrongColor : curChochBear > 0 ? chochDownStrongColor : tableBgColor
        
        string bosTextLive = ""
        if curBosBull > 0 and curBosBear > 0
            bosTextLive := str.tostring(curBosBull) + "U " + str.tostring(curBosBear) + "D"
        else if curBosBull > 0
            bosTextLive := str.tostring(curBosBull) + "U"
        else if curBosBear > 0
            bosTextLive := str.tostring(curBosBear) + "D"
        color bosColorLive = curBosBull > 0 and curBosBear > 0 ? colorMid : curBosBull > 0 ? bosUpStrongColor : curBosBear > 0 ? bosDownStrongColor : tableBgColor
        
        string liqTextLive = ""
        if curLiqBull > 0 and curLiqBear > 0
            liqTextLive := str.tostring(curLiqBull) + "U " + str.tostring(curLiqBear) + "D"
        else if curLiqBull > 0
            liqTextLive := str.tostring(curLiqBull) + "U"
        else if curLiqBear > 0
            liqTextLive := str.tostring(curLiqBear) + "D"
        color liqColorLive = curLiqBull > 0 and curLiqBear > 0 ? colorMid : curLiqBull > 0 or curLiqBear > 0 ?  liqUpColor : tableBgColor
        
        string liveText = formatTime(time) 
        color liveColor = barstate.isrealtime ? color.rgb(0,255,0) : color.yellow
        bool liveDim = getSprdLevel(curSprdMult) < 1
        
        table.cell(tbl, 0, currentRow, liveText, bgcolor=hasAnyEvent ? color.new(colorMid, 80) : tableBgColor, text_color=liveColor, text_size=tSize)
        table.cell(tbl, 1, currentRow, chTextLive, bgcolor=color.new(chColorLive, 90), text_color=chColorLive, text_size=tSize)
        table.cell(tbl, 2, currentRow, bosTextLive, bgcolor=color.new(bosColorLive, 90), text_color=bosColorLive, text_size=tSize)
        table.cell(tbl, 3, currentRow, liqTextLive, bgcolor=color. new(liqColorLive, 90), text_color=liqColorLive, text_size=tSize)
        table.cell(tbl, 4, currentRow, getSprdLabel(curSprdMult), bgcolor=tableBgColor, text_color=dimColor(getSprdColor(curSprdMult), liveDim), text_size=tSize)
        if showDiffColumn
            table.cell(tbl, 5, currentRow, getDiffLabel(curSprdMult, curVolMult), bgcolor=tableBgColor, text_color=dimColor(getDiffColor(curSprdMult, curVolMult), liveDim), text_size=tSize)
            table.cell(tbl, 6, currentRow, getVolLabel(curVolMult), bgcolor=tableBgColor, text_color=dimColor(getVolColor(curVolMult), liveDim), text_size=tSize)
            table.cell(tbl, 7, currentRow, formatPct(curUpperWickPct), bgcolor=tableBgColor, text_color=dimColor(getWickColor(curUpperWickPct), liveDim), text_size=tSize)
            table. cell(tbl, 8, currentRow, formatPct(curBodyPct), bgcolor=tableBgColor, text_color=dimColor(getBodyColor(curBodyPct, curIsBull), liveDim), text_size=tSize)
            table.cell(tbl, 9, currentRow, formatPct(curLowerWickPct), bgcolor=tableBgColor, text_color=dimColor(getWickColor(curLowerWickPct), liveDim), text_size=tSize)
            table.cell(tbl, 10, currentRow, curFlowType, bgcolor=tableBgColor, text_color=dimColor(getFlowColor(curSprdMult, curVolMult), liveDim), text_size=tSize)
            table.cell(tbl, 11, currentRow, curCandleType, bgcolor=tableBgColor, text_color=dimColor(getCandleTypeColor(curCandleType), liveDim), text_size=tSize)
            table.cell(tbl, 12, currentRow, curControl, bgcolor=tableBgColor, text_color=dimColor(getControlColor(curControl), liveDim), text_size=tSize)
        else
            table. cell(tbl, 5, currentRow, getVolLabel(curVolMult), bgcolor=tableBgColor, text_color=dimColor(getVolColor(curVolMult), liveDim), text_size=tSize)
            table.cell(tbl, 6, currentRow, formatPct(curUpperWickPct), bgcolor=tableBgColor, text_color=dimColor(getWickColor(curUpperWickPct), liveDim), text_size=tSize)
            table.cell(tbl, 7, currentRow, formatPct(curBodyPct), bgcolor=tableBgColor, text_color=dimColor(getBodyColor(curBodyPct, curIsBull), liveDim), text_size=tSize)
            table.cell(tbl, 8, currentRow, formatPct(curLowerWickPct), bgcolor=tableBgColor, text_color=dimColor(getWickColor(curLowerWickPct), liveDim), text_size=tSize)
            table.cell(tbl, 9, currentRow, curFlowType, bgcolor=tableBgColor, text_color=dimColor(getFlowColor(curSprdMult, curVolMult), liveDim), text_size=tSize)
            table. cell(tbl, 10, currentRow, curCandleType, bgcolor=tableBgColor, text_color=dimColor(getCandleTypeColor(curCandleType), liveDim), text_size=tSize)
            table.cell(tbl, 11, currentRow, curControl, bgcolor=tableBgColor, text_color=dimColor(getControlColor(curControl), liveDim), text_size=tSize)
        currentRow += 1
    
    // Historical Rows
    int rowsShown = 0
    int arrayIdx = effectiveOffset
    
    while rowsShown < visibleRows and arrayIdx < evtCount
        int chB = array.get(evtChochBull, arrayIdx)
        int chS = array.get(evtChochBear, arrayIdx)
        int bosB = array.get(evtBosBull, arrayIdx)
        int bosS = array.get(evtBosBear, arrayIdx)
        int liqB = array.get(evtLiqBull, arrayIdx)
        int liqS = array.get(evtLiqBear, arrayIdx)
        
        if shouldShowRow(chB, chS, bosB, bosS, liqB, liqS)
            int t = array.get(evtTime, arrayIdx)
            float sprd = array.get(evtSprdMult, arrayIdx)
            float vol = array.get(evtVolMult, arrayIdx)
            float upperWick = array. get(evtUpperWickPct, arrayIdx)
            float body = array.get(evtBodyPct, arrayIdx)
            float lowerWick = array.get(evtLowerWickPct, arrayIdx)
            bool isBull = array.get(evtIsBull, arrayIdx)
            string candleType = array. get(evtCandleType, arrayIdx)
            string flowType = array.get(evtFlowType, arrayIdx)
            string control = array.get(evtControl, arrayIdx)
            
            string chText = ""
            if chB > 0 and chS > 0
                chText := str.tostring(chB) + "U " + str. tostring(chS) + "D"
            else if chB > 0
                chText := str.tostring(chB) + "U"
            else if chS > 0
                chText := str.tostring(chS) + "D"
            color chColor = chB > 0 and chS > 0 ? colorMid : chB > 0 ? chochUpStrongColor : chS > 0 ?  chochDownStrongColor : tableBgColor
            
            string bosText = ""
            if bosB > 0 and bosS > 0
                bosText := str.tostring(bosB) + "U " + str. tostring(bosS) + "D"
            else if bosB > 0
                bosText := str.tostring(bosB) + "U"
            else if bosS > 0
                bosText := str.tostring(bosS) + "D"
            color bosColor = bosB > 0 and bosS > 0 ? colorMid : bosB > 0 ? bosUpStrongColor : bosS > 0 ? bosDownStrongColor : tableBgColor
            
            string liqText = ""
            if liqB > 0 and liqS > 0
                liqText := str.tostring(liqB) + "U " + str. tostring(liqS) + "D"
            else if liqB > 0
                liqText := str.tostring(liqB) + "U"
            else if liqS > 0
                liqText := str.tostring(liqS) + "D"
            color liqColorCell = liqB > 0 and liqS > 0 ?  colorMid : liqB > 0 or liqS > 0 ? liqUpColor : tableBgColor
            
            bool dim = getSprdLevel(sprd) < 1
            
            string timeText = ""
            if tableFilterMode != "All Candles"
                timeText := "#" + str.tostring(arrayIdx) + " " + formatTime(t)
            else if effectiveOffset > 0
                timeText := str.tostring(arrayIdx) + "|" + formatTime(t)
            else
                timeText := formatTime(t)
            
            table.cell(tbl, 0, currentRow, timeText, bgcolor=tableBgColor, text_color=dimColor(textColor, dim), text_size=tSize)
            table. cell(tbl, 1, currentRow, chText, bgcolor=color.new(chColor, 90), text_color=chColor, text_size=tSize)
            table.cell(tbl, 2, currentRow, bosText, bgcolor=color.new(bosColor, 90), text_color=bosColor, text_size=tSize)
            table.cell(tbl, 3, currentRow, liqText, bgcolor=color.new(liqColorCell, 90), text_color=liqColorCell, text_size=tSize)
            table. cell(tbl, 4, currentRow, getSprdLabel(sprd), bgcolor=tableBgColor, text_color=dimColor(getSprdColor(sprd), dim), text_size=tSize)
            if showDiffColumn
                table.cell(tbl, 5, currentRow, getDiffLabel(sprd, vol), bgcolor=tableBgColor, text_color=dimColor(getDiffColor(sprd, vol), dim), text_size=tSize)
                table.cell(tbl, 6, currentRow, getVolLabel(vol), bgcolor=tableBgColor, text_color=dimColor(getVolColor(vol), dim), text_size=tSize)
                table.cell(tbl, 7, currentRow, formatPct(upperWick), bgcolor=tableBgColor, text_color=dimColor(getWickColor(upperWick), dim), text_size=tSize)
                table.cell(tbl, 8, currentRow, formatPct(body), bgcolor=tableBgColor, text_color=dimColor(getBodyColor(body, isBull), dim), text_size=tSize)
                table.cell(tbl, 9, currentRow, formatPct(lowerWick), bgcolor=tableBgColor, text_color=dimColor(getWickColor(lowerWick), dim), text_size=tSize)
                table.cell(tbl, 10, currentRow, flowType, bgcolor=tableBgColor, text_color=dimColor(getFlowColor(sprd, vol), dim), text_size=tSize)
                table.cell(tbl, 11, currentRow, candleType, bgcolor=tableBgColor, text_color=dimColor(getCandleTypeColor(candleType), dim), text_size=tSize)
                table.cell(tbl, 12, currentRow, control, bgcolor=tableBgColor, text_color=dimColor(getControlColor(control), dim), text_size=tSize)
            else
                table. cell(tbl, 5, currentRow, getVolLabel(vol), bgcolor=tableBgColor, text_color=dimColor(getVolColor(vol), dim), text_size=tSize)
                table. cell(tbl, 6, currentRow, formatPct(upperWick), bgcolor=tableBgColor, text_color=dimColor(getWickColor(upperWick), dim), text_size=tSize)
                table. cell(tbl, 7, currentRow, formatPct(body), bgcolor=tableBgColor, text_color=dimColor(getBodyColor(body, isBull), dim), text_size=tSize)
                table.cell(tbl, 8, currentRow, formatPct(lowerWick), bgcolor=tableBgColor, text_color=dimColor(getWickColor(lowerWick), dim), text_size=tSize)
                table.cell(tbl, 9, currentRow, flowType, bgcolor=tableBgColor, text_color=dimColor(getFlowColor(sprd, vol), dim), text_size=tSize)
                table.cell(tbl, 10, currentRow, candleType, bgcolor=tableBgColor, text_color=dimColor(getCandleTypeColor(candleType), dim), text_size=tSize)
                table.cell(tbl, 11, currentRow, control, bgcolor=tableBgColor, text_color=dimColor(getControlColor(control), dim), text_size=tSize)
            
            currentRow += 1
            rowsShown += 1
        
        arrayIdx += 1
    
    // Footer
    int footerRow = currentRow + 1
    
    int filteredCount = 0
    if evtCount > 0
        for i = 0 to evtCount - 1
            int chB = array. get(evtChochBull, i)
            int chS = array.get(evtChochBear, i)
            int bosB = array.get(evtBosBull, i)
            int bosS = array.get(evtBosBear, i)
            int liqB = array. get(evtLiqBull, i)
            int liqS = array. get(evtLiqBear, i)
            if shouldShowRow(chB, chS, bosB, bosS, liqB, liqS)
                filteredCount += 1
    
    [fChB, fChS, fBosB, fBosS, fLiqB, fLiqS, fBuyScore, fSellScore] = calcWindowStats(avgLookback)
    
    int totalBull = fChB + fBosB + fLiqB
    int totalBear = fChS + fBosS + fLiqS
    int totalEvents = totalBull + totalBear
    
    float bullPct = totalEvents > 0 ?  (float(totalBull) / float(totalEvents)) * 100 : 50
    float bearPct = totalEvents > 0 ? (float(totalBear) / float(totalEvents)) * 100 : 50
    
    string filterInfo = tableFilterMode != "All Candles" ? " | FILTER: " + str.tostring(filteredCount) : ""
    string footerText = "BULL:" + str.tostring(bullPct, "#.#") + "% | BEAR:" + str.tostring(bearPct, "#.#") + "% | BUY:+" + str.tostring(fBuyScore) + " | SELL:+" + str. tostring(fSellScore) + filterInfo
    color footerColor = bullPct > 55 ?  colorBull : bearPct > 55 ?  colorBear : colorGray
    
    table.cell(tbl, 0, footerRow, footerText, bgcolor=footerBgColor, text_color=footerColor, text_size=tSize, text_halign=text.align_center)
    table.merge_cells(tbl, 0, footerRow, mergeEnd, footerRow)

// ════════════════════════════════════════════════════════════════════════════════
// ALERTS
// ════════════════════════════════════════════════════════════════════════════════

alertcondition(curChochBull > 0 and curChochBullStrong, title="CHoCH Bullish Strong", message="STRONG CHoCH UP - Bullish Change of Character!")
alertcondition(curChochBull > 0 and not curChochBullStrong, title="CHoCH Bullish Weak", message="weak choch up - Bullish Change of Character")
alertcondition(curChochBear > 0 and curChochBearStrong, title="CHoCH Bearish Strong", message="STRONG CHoCH DN - Bearish Change of Character!")
alertcondition(curChochBear > 0 and not curChochBearStrong, title="CHoCH Bearish Weak", message="weak choch dn - Bearish Change of Character")
alertcondition(curBosBull > 0 and curBosBullStrong, title="BOS Bullish Strong", message="STRONG BOS UP - Bullish Break of Structure!")
alertcondition(curBosBull > 0 and not curBosBullStrong, title="BOS Bullish Weak", message="weak bos up - Bullish Break of Structure")
alertcondition(curBosBear > 0 and curBosBearStrong, title="BOS Bearish Strong", message="STRONG BOS DN - Bearish Break of Structure!")
alertcondition(curBosBear > 0 and not curBosBearStrong, title="BOS Bearish Weak", message="weak bos dn - Bearish Break of Structure")
alertcondition(curLiqBull > 0, title="LIQ Bullish", message="LIQ UP - Liquidity Sweep Above!")
alertcondition(curLiqBear > 0, title="LIQ Bearish", message="LIQ DN - Liquidity Sweep Below!")
alertcondition(curLiqBull > 0 and curLiqBear > 0, title="DUAL LIQ", message="DUAL LIQ - Both Sides Swept!")

// ════════════════════════════════════════════════════════════════════════════════
// END OF SCRIPT v23
// ════════════════════════════════════════════════════════════════════════════════

Overview

A volume strength filter compares the breaking bar with the last few bars or with a tape average, and weak breaks can be shown or hidden. Swing high and low lines are styled by whether they are active, touched or broken, with adjustable colours, widths and line styles. Swing lookback and maximum stored swings are configurable.

Details

Published by

Blendoxius on GitHub

Type

Indicator, Pine Script v6

Draws

On the price chart

Category

SMC / ICT / price action, Volume, 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
Max Swingsint50maxSwings
Enable CHoCHbooltrueenableChoch
Enable BOSbooltrueenableBos
Enable LIQbooltrueenableLiq
Enable Volume FilterbooltrueenableVolumeFilter
Compare ModestringCustom BarsvolumeCompareMode
Compare to Last X Barsint3volumeCompareBars
Strength Thresholdfloat1.0volumeStrengthThreshold
Apply to CHoCHbooltrueapplyFilterToChoch
Show Weak CHoCHbooltrueshowWeakChoch
Show Weak BOSbooltrueshowWeakBos
Active Colorcolorcolor. rgb(244,67,54)swingHighActiveColor
Show all 40 settings
SettingTypeDefaultVariable
Widthint1swingHighActiveWidth
StylestringsolidswingHighActiveStyle
StylestringsolidswingHighBrokenStrongStyle
Weak Colorcolorcolor. rgb(100,100,100)swingHighBrokenWeakColor
Widthint1swingHighBrokenWeakWidth
Touched Colorcolorcolor.rgb(255,193,7)swingHighTouchedColor
Widthint1swingHighTouchedWidth
StylestringdashedswingHighTouchedStyle
Active Colorcolorcolor.rgb(76,175,80)swingLowActiveColor
Widthint1swingLowActiveWidth
StylestringsolidswingLowActiveStyle
Strong Colorcolorcolor.rgb(255,0,0)swingLowBrokenStrongColor
Widthint2swingLowBrokenStrongWidth
StylestringsolidswingLowBrokenStrongStyle
Weak Colorcolorcolor.rgb(100,100,100)swingLowBrokenWeakColor
Widthint1swingLowBrokenWeakWidth
StylestringdottedswingLowBrokenWeakStyle
Touched Colorcolorcolor. rgb(255,193,7)swingLowTouchedColor
StylestringdashedswingLowTouchedStyle
Show CHoCH LabelsbooltrueshowChochLabels
Up Strongcolorcolor.rgb(0,255,255)chochUpStrongColor
Down Strongcolorcolor. rgb(255,165,0)chochDownStrongColor
Down Weakcolorcolor.rgb(150,100,0)chochDownWeakColor
Label SizestringsmallchochLabelSizeStr
Label PositionstringBreak PointchochLabelPosition
Show BOS LabelsbooltrueshowBosLabels
Up Strongcolorcolor.rgb(0,255,0)bosUpStrongColor
Up Weakcolorcolor. rgb(0,120,0)bosUpWeakColor
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

Moon Dev GEX Sweep & CVD

by moondevonyt
92 stars

The indicator detects liquidity sweeps across key price levels and calculates a cumulative volume delta proxy. It uses pivot high and low lookbacks to identify swing points, marking sweeps when price breaks beyond a level and quickly closes back inside. Featur

Indicator v5 Support & resistanceSMC / ICT / price action
Updated 2 months ago · Custom licence GitHub repository of Moon Dev GEX Sweep & CVD

Calculates higher-timeframe volume profiles to identify Value Area High (VAH), Value Area Low (VAL), and Point of Control (POC) levels directly on the price chart. It flags potential reversal setups and Change in State of Delivery (CISD) patterns relative to v

Indicator v6 VolumeSupport & resistance
Updated 2 months ago · None stated GitHub repository of CandelaCharts - Value Area Reversals

Copilot

by milocaetano
48 stars

Copilot is an order flow range-reversal indicator designed to overlay trading setups directly on the price chart. It evaluates four criteria: market context (sideways vs trending regime based on ATR height), structure (double top or double bottom retests), abs

Indicator v5 SMC / ICT / price actionSupport & resistance
Updated 2 days ago · MIT GitHub repository of Copilot

Supply and Demand Visible Range identifies supply, demand, and equilibrium zones across the visible chart range. It accumulates high, low, and volume data starting from the leftmost visible bar, optionally requesting lower timeframe intrabar data for finer res

Indicator v5 Support & resistanceVolume Repaints
Updated 2 months ago · AGPL-3.0 GitHub repository of Supply and Demand Visible Range [LuxAlgo]
13 stars

This script identifies and visualizes bullish and bearish order blocks on the price chart. It detects low-volatility consolidation ranges followed by breakout moves accompanied by high trading volume. Users can select between Simple, Relative, or Weighted volu

Indicator v6 SMC / ICT / price actionSupport & resistance
Updated 6 months ago · MIT GitHub repository of Advanced Order Blocks with Volume

This indicator identifies and visualizes key support and resistance heatmap zones directly on the price chart. Using closed one-hour price data, it evaluates multi-scale pivots, liquidity clusters, relative volume, and round-number resonances to score structur

Indicator v6 Support & resistanceSMC / ICT / price action
Updated 7 weeks ago · MIT GitHub repository of 加密货币1小时关键价位热力图 V2

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