ThisPineScriptOderflowV23.txt
Copy
// 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
// ════════════════════════════════════════════════════════════════════════════════
Show all 1,212 lines