Isolated Scroll Container

1. Volumetric Order Flow Structure Strategy Description

Detects market-structure breaks (BOS/CHoCH) via pivots, attaching a "delta" bar showing the conviction of the breakout candle, a synthetic 15-row Volume Profile built from the pivot candle itself, and manipulation bubbles that flag liquidity grabs against still-active structure zones.

1.1 Indicator Concept

This indicator belongs to the same Break of Structure (BOS) / Change of Character (CHoCH) family as many other Smart Money Concepts tools: when price closes past the nearest swing pivot, that's evidence market structure has just changed. What sets it apart is that it attaches a "volumetric signature" to every break:

  • Delta / Conviction Bar: a 3-layer horizontal bar whose "filled" inner portion is longer or shorter depending on how close the BREAKOUT CANDLE's close settled to the edge favoring the break's direction - the closer to the favorable edge, the longer the fill (higher conviction behind the break).
  • Synthetic 15-Row Volume Profile: NOT real volume-at-price (no lower-timeframe data involved) - a geometric approximation instead. It divides the range of the PIVOT CANDLE ITSELF (not the breakout candle) into 15 rows, each given a bell-shaped weight (highest near the middle, tapering toward both edges), plus a bonus for any row that overlaps the candle's real body. The highest-weighted row is labeled "POC" (Point of Control) in orange.
  • Manipulation Bubbles: while a structure zone ("Order Block") is still active, if price wicks past its boundary and gets rejected (no close-through), the indicator draws a warning bubble sized proportionally to that candle's relative volume - a flag for "liquidity was just hunted" right at the zone's edge.

Every break becomes a continuously tracked "Order Block" object that lives until price closes back through it ("mitigation" - it's invalidated), or gets retired FIFO-style once the number of active blocks exceeds the allowed limit.

1.2 Indicator Features

  • 3-Layer Volumetric Structure Bar + BOS/CHoCH Label: a horizontal bar made of a faint background layer, a "glow" layer, and a solid core layer, spanning from the pivot candle to the confirmation candle, with a "BOS" (continuation) or "CHoCH" (reversal) label - drawn PERMANENTLY, never deleted afterward, acting as a historical marker of the break event.
  • 15-Row Volume Profile (over the Order Block's range): horizontal colored bands covering the zone's height, rows overlapping the real candle body drawn more opaque than rows only overlapping a wick. The bands' right edge keeps extending every bar while the block stays active.
  • Mini Histogram (right side of chart): a horizontal-bar-chart rendering of the same 15 weights, bar length proportional to weight, POC row colored orange, the rest colored by the block's bull/bear color.
  • Manipulation Bubble + Volume Label: a warning circle appears exactly where price pierced a block's boundary and got rejected, with a text label showing that candle's volume (shorthand format "1.5K", "2.3M"...), bubble size split into 5 tiers (tiny → huge) based on relative volume.
  • Overlap filter (optional): when enabled, a new block is only drawn if its volume is GREATER than every active block it overlaps in price - weaker overlapping blocks get deleted to make room, keeping the chart cleaner where many pivots occur close together.
  • Max active block cap (FIFO): once the number of blocks exceeds "Max Recent Blocks", the OLDEST one (by creation order, not price) is deleted immediately, regardless of whether it's still price-valid.
  • No color inputs, no alerts: unlike several other BOS/CHoCH indicators in this series, the bull/bear/POC colors here are hardcoded constants with no color picker, and the indicator ships with zero alertcondition() calls.

1.3 How to Use the Indicator

  • Distinguish BOS from CHoCH to read context correctly: "BOS" is a break in the SAME direction as the current trend (continuation), "CHoCH" is a break AGAINST the current trend (the first sign of a reversal) - these two signal types should be handled with different strategic weight.
  • Use the Order Block's [low, high] range as a dynamic support/resistance zone: when price returns to it and bounces, the zone stays "alive" on the chart; the moment price closes fully through it, every live drawing tied to that block disappears - a signal the zone has been invalidated and is no longer trustworthy.
  • Treat a manipulation bubble as a liquidity-trap warning: a large bubble (high relative volume) appearing exactly at a block's boundary without a close-through suggests the level was just defended by real participation - adding confidence if price then reverses back into the block.
  • Read the delta bar's filled length as a proxy for breakout conviction: a longer fill (nearly spanning the whole bar) means the breakout candle closed very close to its favorable edge - a strong, decisive break; a short fill means it closed near the unfavorable edge - a weak signal, more prone to failing.
  • Don't treat the orange POC row as an actual traded-volume level: it's an illustrative synthetic shape (bell curve + body bonus), not a real volume profile computed from tick/lower-timeframe data - read it only as "where the pivot candle's body was most concentrated within its own range".
  • Tune "Max Recent Blocks" and "Hide Overlapping Blocks" to control chart clutter on lower timeframes where pivots occur frequently and back-to-back.

1.4 How the Indicator Works

Inputs & Roles

  • pivotLenInput ("Pivot Length", Integer, default: 3): number of bars on each side used to confirm a pivot high/low. Example: pivotLenInput=3 means a swing high is only confirmed 3 bars after it forms - a minimum 3-bar lag. Increase → only catches major swing points, fewer but more reliable BOS/CHoCH events. Decrease → more events, less lag but noisier.
  • volLookbackInput ("Volume Lookback", Integer, default: 20): number of bars summed into the totalVolume variable.
  • maxObsInput ("Max Recent Blocks", Integer, default: 5): maximum number of Order Blocks allowed to be active simultaneously. Example: when a 6th block is created while 5 previous ones are still "alive" → the OLDEST one (created first) is deleted immediately to make room, regardless of whether it's still price-valid. Increase → keeps more structural history visible but the chart gets more cluttered. Decrease → cleaner chart but old blocks vanish sooner.
  • boxTransparencyInput ("Base Transparency", Integer 0-100, default: 80): base transparency of the 15-row Volume Profile bands. Rows overlapping the real candle body are always drawn 10 points more opaque than this value (more visible), rows only overlapping a wick are 10 points more transparent.
  • hideOverlappingInput ("Hide Overlapping Blocks", Boolean, default: false): when ON, a new block is only drawn if the pivot candle's volume that created it is GREATER than every active block whose price range it overlaps; if so, all weaker overlapping blocks are fully deleted before the new one is drawn.
  • showManipulationInput ("Show Manipulation Bubbles", Boolean, default: true): toggles the liquidity-grab warning bubbles.
  • manipSizeInput ("Bubble Sensitivity", Float, default: 1.0, min 0.1): multiplier applied to the relative-volume ratio before bucketing bubble size. Example: candle volume = 1500, highest volume over 200 bars = 5000, manipSizeInput=1.0 → ratio = (1500/5000)×1.0 = 0.30 → falls into the "small" tier. Increase → the same actual volume produces a bigger bubble (easier to reach "huge"). Decrease → smaller bubbles for the same volume.
💡 Note on the "Volume Profile": the 15 row weights in this indicator are NOT computed from real volume-at-price data (unlike a genuine volume-profile tool that uses lower-timeframe candles) - it's a synthetic geometric formula: a bell-shaped weight (highest at the zone's middle, lowest at both edges) plus a flat bonus for any row that overlaps the real candle body. Also, all the OHLC/volume data used to build BOTH the delta bar AND the 15-row profile (pHigh/pLow/pOpen/pClose/pVol) comes from the PIVOT CANDLE ITSELF (the bar where the swing high/low formed) - the one exception is the delta bar's fill percentage (deltaPct), which is computed from the BREAKOUT CONFIRMATION candle (the current bar at the moment of the break) instead.

Main Logic Blocks

🎯 Flow 1: Pivot Detection

  • ta.pivothigh(pivotLenInput, pivotLenInput) and ta.pivotlow(...) confirm a swing high/low once enough bars exist on both sides. When a new pivot forms: save lastPh/lastPl = the pivot's price, lastPhIdx/lastPlIdx = the pivot's TRUE bar position (bar_index - pivotLenInput, stepping back exactly the confirmation lag).
  • Example: pivotLenInput=3. A swing high forms at bar 500, confirms at bar 503 → lastPh := the high's price, lastPhIdx := 503 - 3 = 500 (correctly points back to the actual pivot bar, not the confirmation bar).

🎯 Flow 2: Breakout Detection & BOS/CHoCH Labeling

  • isCrossover = ta.crossover(close, lastPh): when true and lastPh still exists → calls draw_structure() with label "CHoCH" if the current trend is -1 (bearish, i.e. this is a reversal), or "BOS" otherwise (already +1 or neutral, i.e. a continuation) → updates trend := 1 → clears lastPh (so this pivot can't retrigger a second time).
  • isCrossunder is symmetric using lastPl, setting trend := -1.
  • Example: lastPh=1.2700 (from bar 500), current trend = -1. At bar 530, close=1.2705 crosses above 1.2700 → calls draw_structure(500, 1.2700, "CHoCH", BULL_COLOR, true) (since trend==-1 → a reversal); trend := 1; lastPh is cleared.

🔍 Flow 3: Overlap Filtering (if enabled)

  • Scans all of activeObs for blocks whose price range [low, high] overlaps the block about to be created. If ANY overlapping block has volume ≥ the new pivot candle's volume → skip drawing the new block entirely (shouldDraw := false). Otherwise, delete all the (weaker) overlapping blocks before proceeding to draw the new one.

🖊️ Flow 4: Drawing the Volumetric Structure Bar

  • range_ = the high-low range of the BREAKOUT CONFIRMATION candle (the current bar). deltaPct = how close that candle's close settled to the edge favoring the break's direction (e.g. for a bullish break: (close-low)/range_).
  • dist = the number of bars from the pivot to now. fillEnd = pivot + round(dist × max(0.1, deltaPct)) - this is where the "filled" portion (glow + core) of the bar ends; the remainder (faint background only) stretches on to the current bar.
  • Draws 3 stacked boxes: a very faint background (92% transparent, full length), a glow (80% transparent, length up to fillEnd), and a solid core (20% transparent, same length as glow) - none of these 3 boxes are stored in any array, so they persist PERMANENTLY on the chart. The "BOS"/"CHoCH" label is the same - drawn once, never deleted.
  • Example: pivot at bar 500, breakout confirms at bar 530 → dist=30. Bar 530 has high=1.2710, low=1.2695, close=1.2705, isBullish=true → range_=0.0015, deltaPct=(1.2705-1.2695)/0.0015=0.667 → fillEnd=500+round(30×0.667)=500+20=520. The filled portion spans bar 500 to 520 (~67% of the bar's length), the rest (520→530) shows only the faint background layer.

🧮 Flow 5: Building the Synthetic 15-Row Volume Profile

  • Divides the PIVOT CANDLE's [pLow, pHigh] range into 15 equal rows (rowStep). For each row i: distFromMid = |i - 7.5|, a base weight w = max(2, 12 - distFromMid×1.5) (bell-shaped, highest at the middle, lowest at both edges); if that row overlaps the real candle body (between pOpen and pClose) → add 5.
  • The highest-weighted row becomes pocIndex (POC, colored orange). Two box sets are then drawn per row: colored bands covering the Order Block's range (boxes, right edge keeps extending every bar while the block stays alive) and a bar in the mini histogram on the right side of the chart (histBoxes, length = weight).
  • Example: pHigh=1.2720, pLow=1.2680 → rowStep=0.002667. Row i=7 (closest to middle): distFromMid=0.5 → w=max(2,12-0.5×1.5)=11; if it overlaps the body → w=16 → usually becomes the POC. Row i=0 (top edge): distFromMid=7.5 → w=max(2,12-7.5×1.5)=max(2,0.75)=2 (minimum floor), unless it also overlaps the body (then +5=7).

📦 Flow 6: Registering the New Order Block + FIFO Cap

  • The new block (with all its boxes and weights just built) is pushed into activeObs. If the array's size exceeds maxObsInput → array.shift() pulls out and deletes the FRONT element (oldest by creation order) - deleting every box/label it owns.

🗑️ Flow 7: Per-Bar Update - Mitigation Check

  • Every bar, iterates backward through every block in activeObs: mitigated = true if a bullish block's close drops below ob.low, or a bearish block's close rises above ob.high. If true: delete ALL of that block's profile boxes, histogram boxes, manipulation bubbles, and accumulated volume labels, then remove it from the array.
  • Example: a bullish block with ob.low=1.2680. Price later closes at 1.2675 (<1.2680) → mitigated=true → every live drawing tied to that block is deleted. The original 3-layer delta bar + BOS/CHoCH label (not tracked in any array) remain untouched on the chart forever as a historical marker.

🔄 Flow 8: Per-Bar Update - Extending Live Drawings

  • For blocks NOT yet mitigated: the right edge of every profile box is extended to bar_index + 10; the histogram boxes' coordinates are reassigned (using the same stored weights and bounds - values don't actually change).

🫧 Flow 9: Manipulation Detection

  • For still-active blocks: raidHigh = the block is bearish AND the current high > ob.high AND the current close ≤ ob.high (price wicked above the boundary then got rejected). raidLow is symmetric for a bullish block.
  • When true: manipVolScale = (current bar's volume / highest volume over 200 bars) × manipSizeInput, bucketed into 5 size tiers (tiny through huge). Draws one circle bubble (colored BEAR_COLOR if raidHigh, BULL_COLOR if raidLow) + one text label showing the shorthand volume, both stored into that block's arrays to be deleted together later when the block is mitigated or FIFO-retired.
  • Example: a bearish block with ob.high=1.2650. Current bar: high=1.2658 (>1.2650), close=1.2645 (≤1.2650) → raidHigh=true. Candle volume=1500, highest volume over 200 bars=5000, manipSizeInput=1.0 → ratio=(1500/5000)×1.0=0.30 → falls into the "small" tier. A red bubble (BEAR_COLOR) appears at price 1.2658, the text label shows "1.5K".

Outputs & Usage Roles

  • Delta bar + BOS/CHoCH label: a permanent historical marker pinpointing exactly when, at what price, and with how much conviction each structure break occurred.
  • 15-row Volume Profile bands + histogram + POC row: a visual read of "where the pivot candle's body was concentrated within its own range" - a reference for a likely reaction zone when price revisits the block.
  • Manipulation bubbles + labels: a live warning that an active block's boundary was just tested and defended, sized by relative volume.
  • A block's disappearance: signals price has decisively closed through it (mitigated) - that structural reference is no longer valid.
💡 Additional note: the totalVolume variable (computed from volLookbackInput) is declared but NEVER referenced anywhere else in the script - this is existing behavior of the original indicator (a dead/leftover variable), not something introduced by this analysis, and no functionality should be invented for it. The indicator also has no customizable colors (BULL_COLOR/BEAR_COLOR/POC_COLOR are hardcoded constants) and no alertcondition() calls - if automated alerts or custom colors are needed, add them during Phase B (Strategy conversion).
Zoom/Pan Layered Image
Background Overlay
− +

The indicator above just became a TRADING BOT — 1 AI click

📊Original indicator
→
🤖AI 1-click convert
→
⚙️Bot trading 24/7