Auction Intelligence█ AUCTION INTELLIGENCE
Auction Market Theory Overlay
An Auction Market Theory (AMT) overlay that analyzes market structure through volume profile analysis. It detects profile shape (D/P/b/DD), identifies balance vs. imbalance states, and tracks value migration — giving you the same auction-based framework used by institutional traders to understand market behavior.
Free and Open Source.
█ THE CONCEPT: WHY AUCTION MARKET THEORY MATTERS
Standard indicators tell you what happened. AMT tells you why . Markets are continuous two-sided auctions where buyers and sellers negotiate fair value:
Balance — Price rotates within an accepted value area. Expect mean-reversion and range-bound trading.
Imbalance — Price breaks away from the value area. One side dominates. Expect continuation.
Profile Shape — The distribution of volume tells you who is in control and what to expect next.
Value Migration — The direction where the POC and Value Area are shifting reveals the underlying trend.
█ CORE FEATURES
1. Volume Profile Engine
Distributes each bar's volume proportionally across price rows, building a volume-at-price distribution:
POC (Point of Control) — Highest volume row = strongest S/R level
VAH (Value Area High) — Upper boundary of the 70% value area = resistance
VAL (Value Area Low) — Lower boundary of the 70% value area = support
2. Profile Shape Detection
Automatically classifies the volume distribution into four distinct shapes:
D-shape — Balanced. Volume evenly distributed, POC near center. Expect rotation.
P-shape — Bullish. Volume concentrated in upper half. Buyers in control.
b-shape — Bearish. Volume concentrated in lower half. Sellers in control.
DD (Double Distribution) — Two distinct volume clusters. Market transitioning between value areas.
3. Balance vs. Imbalance Recognition
Three-factor analysis combining price position, VA width dynamics, and trend strength. The chart background colors automatically when imbalance is detected (cyan = bullish discovery, red = bearish discovery).
4. Value Migration Tracker
Monitors how the POC and Value Area midpoint shift over time:
Bullish Migration ▲ — POC and VA migrating higher = institutional buying
Bearish Migration ▼ — POC and VA migrating lower = institutional selling
Neutral ─ — No significant migration = consolidation
█ AUTO-TIMEFRAME ADAPTATION
All parameters automatically adjust based on the chart timeframe:
1-5 min → Lookback 30, 18 Rows, Migration Len 5
15-30 min → Lookback 40, 20 Rows, Migration Len 8
1 Hour → Lookback 50, 24 Rows, Migration Len 10
4 Hour → Lookback 70, 28 Rows, Migration Len 15
Daily → Lookback 100, 32 Rows, Migration Len 20
Weekly+ → Lookback 150, 40 Rows, Migration Len 30
Disable Auto-TF to use manual settings for full control.
█ DASHBOARD
A compact, dark-themed info panel displaying:
State — Current AMT state (BALANCE / IMBALANCE) with context
Shape — Detected profile shape (D / P / b / DD) with description
Migration — Value migration direction and strength
Position — Current price position relative to Value Area
POC / VAH / VAL — Key volume-based levels
█ ALERTS (4 CONDITIONS)
Balance → Imbalance — Market leaving the value area
Imbalance → Balance — Market returning to the value area
Profile Shape Changed — Volume distribution pattern shift
Value Migration Shift — Directional bias change in POC/VA migration
█ PRO VERSION
The PRO version (Auction Intelligence PRO v2.0) adds:
Initial Balance Range — IB Tracking + IB Extension Detection
Failed Auction Detection — VA Breakout Failures
Excess & Poor High/Low — Wick analysis at session extremes
Auction Rotation Factor — POC-cross frequency as market efficiency measure
Day Type Classification — Trend/Normal/Normal Var./Neutral/Double Dist. (Dalton)
Previous Day Value Area — PDPOC/PDVAH/PDVAL as reference levels
Enhanced Confluence Score — 0-12 scale with A+ to D grading
13 Alert Conditions
█ NON-REPAINTING
The volume profile is calculated from confirmed bar data only. The rolling lookback window recalculates on each confirmed bar using historical high/low/volume — no future data is used. No repainting.
█ WORKS ON
Crypto, Forex, Stocks, Futures, Indices — any timeframe from 1 minute to Monthly.
█ DISCLAIMER
This indicator is for educational and informational purposes only. It does not constitute financial advice. Always do your own research and manage your risk. Past performance does not guarantee future results. Trading involves substantial risk of loss.
지표

Volume Profile█ VOLUME PROFILE
Volume-at-Price Analysis with POC, VAH & VAL
A powerful volume-at-price analysis overlay that calculates and visualizes the Point of Control (POC) , Value Area High (VAH) , and Value Area Low (VAL) directly on your chart. It reveals where the most trading activity occurred and provides real-time price position analysis — helping you identify high-probability support/resistance levels and mean-reversion zones.
Free and Open Source.
█ THE CONCEPT: WHY VOLUME PROFILE MATTERS
Price charts show when trading happened. Volume Profile shows where it happened. The distribution of volume across price levels reveals the market's true valuation zones:
Point of Control (POC) — The price with the highest accumulated volume. Acts as a magnet for price and the strongest single S/R level.
Value Area (70%) — The range containing 70% of all traded volume. Defines what the market considers "fair value."
Above/Below VA — Price outside the value area signals potential overextension or breakout.
Institutional traders, market makers, and algorithmic systems all reference volume profile levels.
█ CORE FEATURES
1. Volume Profile Engine
Distributes each bar's volume proportionally across the price rows it spans, building a precise volume-at-price histogram:
POC — Highest volume row = strongest support/resistance
VAH — Upper boundary of the 70% value area = resistance
VAL — Lower boundary of the 70% value area = support
Row count is configurable (10-50 levels).
2. Profile Anchoring
Three anchor modes control how the profile is built:
Rolling — Continuously recalculated over the last N bars. Best for real-time analysis.
Session — Resets every new trading day. Best for intraday context.
Week — Resets every new trading week. Best for swing context.
3. Price Position Analysis
Real-time classification of price relative to the value area:
ABOVE VA — Potential overextension or breakout
BELOW VA — Potential undervaluation or breakdown
AT POC — High-probability mean-reversion zone
IN VA — Normal trading range
4. Bounce & Rejection Signals
Automatic detection of price interaction with key volume levels:
POC Bounce Up/Down — Price touches POC and reverses
VAL Rejection — Price tests VAL and bounces up (bullish)
VAH Rejection — Price tests VAH and bounces down (bearish)
5. Volume Histogram Visualization
A horizontal bar chart displayed directly on the price chart showing the volume distribution. POC row highlighted with a distinct color.
█ AUTO-TIMEFRAME ADAPTATION
All parameters automatically adjust based on the chart timeframe:
1-5 min → Lookback 30, 18 Rows, Histogram Width 8
15-30 min → Lookback 40, 20 Rows, Histogram Width 10
1 Hour → Lookback 50, 24 Rows, Histogram Width 15
4 Hour → Lookback 70, 28 Rows, Histogram Width 18
Daily → Lookback 100, 32 Rows, Histogram Width 22
Weekly+ → Lookback 150, 40 Rows, Histogram Width 30
█ DASHBOARD
A compact, dark-themed info panel displaying:
POC — Current Point of Control price level
VAH / VAL — Value Area boundaries
Position — Current price position (ABOVE VA / BELOW VA / AT POC / IN VA)
To POC — Distance from current price to POC in percent
Anchor — Active profile anchor mode
VA Range — Width of the value area in price units
█ ALERTS (4 CONDITIONS)
POC Bounce Up — Bullish bounce off the Point of Control
POC Bounce Down — Bearish bounce off the Point of Control
VAL Rejection — Bullish rejection at Value Area Low
VAH Rejection — Bearish rejection at Value Area High
█ NON-REPAINTING
The volume profile is calculated from confirmed bar data only. Rolling mode recalculates the full lookback window on each bar using historical high/low/volume — no future data is used. Session and Week modes accumulate incrementally within the anchor period. No repainting.
█ WORKS ON
Crypto, Forex, Stocks, Futures, Indices — any timeframe from 1 minute to Monthly.
█ DISCLAIMER
This indicator is for educational and informational purposes only. It does not constitute financial advice. Always do your own research and manage your risk. Past performance does not guarantee future results. Trading involves substantial risk of loss.
지표

AG Pro Volume Profile POC Magnet Map [AGPro Series]AG Pro Volume Profile POC Magnet Map
Overview
AG Pro Volume Profile POC Magnet Map is a chart-overlay indicator built around one practical question: how strongly is the current Point of Control attracting, holding, or losing price?
Instead of trying to replicate a full volume-profile workstation, this script focuses on the behavior of the active POC and the surrounding value area. The goal is to turn a familiar volume-profile concept into a cleaner decision-support map that helps users judge whether price is still interacting with the current fair-value center, rejecting it, reclaiming it, or beginning to establish value elsewhere.
The script is designed for users who want a visual framework around POC behavior without covering the chart with heavy histogram structures or overly complex dashboards. It highlights the active POC, the current Value Area High (VAH), the current Value Area Low (VAL), a compact magnet band around the POC, and a small set of reaction labels that describe how price is interacting with that area.
In short, this indicator is not trying to tell users what to buy or sell. It is trying to make one specific market reference more readable: the relationship between price and the current POC region.
What the script does
At a high level, the script does five things:
1) It builds a fixed-lookback volume-distribution map from recent chart data.
2) It derives the active POC, VAH, and VAL from that distribution.
3) It measures how close price is to the current POC and how often price revisits or accepts that region.
4) It converts those observations into a compact Magnet Score and state readout.
5) It marks a small set of price/POC interaction events such as Tag, Reject, and Reclaim.
The result is a visual tool that combines reference levels and contextual interpretation in one overlay.
Unique edge
Many indicators can show a POC. This script is built to answer a more specific question: what is the quality of the current POC as a magnet for price?
That difference matters. A raw POC line can be useful, but by itself it does not explain whether price is repeatedly returning to it, drifting away from it, rejecting it, or stabilizing around it. This script adds that missing context by combining the active POC with a behavior layer.
The design goal is not “more features.” The design goal is clearer interpretation:
- Is price still accepting the current value center?
- Is the POC functioning as a pullback magnet?
- Is price rejecting the area instead of accepting it?
- Is value beginning to migrate?
That is the role of the score, the state engine, and the reaction labels.
Methodology
The script uses a fixed lookback window and divides the recent price range into user-defined bins. It then allocates each bar’s volume to one price bin using the selected bar source, which can be Close or HLC3. From that distribution it identifies:
- POC: the highest-volume bin in the lookback window
- VAH: the upper boundary of the selected value area percentage
- VAL: the lower boundary of the selected value area percentage
After the levels are derived, the script evaluates how price is behaving relative to the active POC region.
The Magnet Score is built from multiple components:
- Distance: how far current price is from the POC, normalized by ATR
- Revisit behavior: how often price has returned to the POC region
- Acceptance behavior: how often price has closed near the POC region
- Stability: whether the POC is relatively stable or drifting quickly
- Rejection pressure: whether interactions with the POC region are ending in rejection rather than acceptance
These components are combined into a bounded 0-100 score. Higher readings suggest that the current POC remains a stronger center of attraction. Lower readings suggest weaker pull, weaker acceptance, or a market beginning to operate away from the current value center.
The script then classifies context into states such as:
- Magnet Strong
- Magnet Active
- POC Tagged
- POC Rejected
- Accepted Away
- Magnet Weakening
This state layer is designed to summarize the current context rather than generate automatic trading instructions.
How to read the chart
POC
The POC is the main reference line. It marks the highest-volume price zone inside the selected lookback distribution. If price repeatedly returns to it, reacts from it, or consolidates around it, that line is functioning as an active center of interest.
VAH and VAL
VAH and VAL define the current value-area boundaries. These help users judge whether price is still operating inside value or beginning to establish acceptance above or below it.
Magnet band
The magnet band is a narrow region around the POC. It exists to make POC interaction easier to read visually. It is not a claim that every touch is meaningful. It is simply a compact visual tolerance zone around the active POC.
Reaction labels
The script can display a small set of event labels:
- Tag: price reached the current POC region
- Reject: price interacted with the area and moved away
- Reclaim: price crossed back through the active POC after being on the other side
These labels are meant to help describe interaction, not to replace confirmation logic, risk management, or broader market context.
Panel
The panel summarizes:
- Magnet Score
- POC Distance
- POC Drift
- Value Context
- Last Reaction
- Current POC / VAH / VAL values
This gives users a quick status view without needing to inspect every line manually.
Typical use cases
This indicator may be useful when users want to:
- monitor whether pullbacks are still returning to the active POC
- judge whether price is still auctioning inside value or beginning to accept away from value
- compare different symbols for how “sticky” the current POC region appears to be
- add context to an existing structure, trend, or mean-reversion workflow
- keep a cleaner chart while still tracking basic volume-profile behavior
The script is intended as a context and interpretation layer. It is not a complete trading plan on its own.
Key inputs
Lookback Bars
Controls the size of the historical window used for the profile calculation. A larger value creates a broader context. A smaller value makes the profile more reactive.
Rows / Bin Count
Controls profile granularity. Higher values create more detailed binning. Lower values produce a smoother, simpler map.
Value Area %
Defines how much of total lookback volume is included inside the value area used to derive VAH and VAL.
Price Source For Bin Allocation
Lets users choose whether each bar’s volume is allocated using Close or HLC3. This changes how the profile is distributed across bins.
ATR Length
Used in normalization and spacing calculations, including the distance component and label positioning.
Magnet Band Width (ATR)
Controls the thickness of the tolerance zone around the active POC.
Distance Ceiling (ATR)
Caps how far price can be from the POC before the distance component is treated as maximally weak.
Revisit Window and Acceptance Window
These affect how the script measures repeated interaction and acceptance around the active POC region.
POC Drift Lookback
Used to estimate whether the active POC is relatively stable or shifting.
Label controls
Users can adjust label visibility, density, cooldown behavior, and right-edge line labels to keep the chart cleaner or more descriptive depending on preference.
Alerts
The script includes alert conditions for:
- POC Tag
- POC Reject
- POC Reclaim
- Magnet Strong
- Magnet Active
- Magnet Weakening
- Accepted Away
These alerts are event-based notifications tied to the script’s contextual logic. They are not performance claims and they should not be interpreted as guaranteed entry or exit signals.
Limitations and transparency
This script uses a fixed-lookback, bar-based approximation of volume distribution. It does not reconstruct native exchange-level order flow, bid/ask delta, or true tick-by-tick auction detail.
Volume is allocated to bins using a selected bar source rather than full intrabar volume-at-price reconstruction. That means the profile is intentionally simplified so it can remain lightweight and readable inside a standard Pine overlay.
Because the script uses a rolling lookback window, the active POC, VAH, and VAL can change as older bars leave the window and newer bars enter it. That is normal behavior for this design.
The reaction labels are descriptive, not predictive. A Tag does not imply reversal. A Reject does not guarantee continuation. A Reclaim does not guarantee trend resumption. They are context markers showing how price interacted with the current POC area according to the script’s definitions.
This tool should be read in conjunction with price structure, volatility, liquidity conditions, and user-defined execution rules.
What this script is not
This script is not:
- a full session volume-profile suite
- an order-flow or footprint tool
- a prediction engine
- a guaranteed reversal detector
- a stand-alone trade system
It is a focused overlay for interpreting how price is behaving around the current Point of Control and value-area structure.
Practical interpretation notes
In many markets, the POC acts like a reference area rather than a directional signal. The more often price returns to it and the more often price stabilizes near it, the more useful that region can become as a working fair-value reference.
By contrast, when price begins to hold above VAH or below VAL and stops interacting meaningfully with the POC region, the script may shift toward weaker magnet states or accepted-away context. That does not automatically imply trend continuation, but it does suggest that the current value center may be losing influence.
Users may find this especially useful when comparing:
- balanced conditions vs. directional conditions
- shallow pullbacks vs. deeper value retests
- symbols that keep rotating through value vs. symbols that are clearly accepting away from it
Risk disclosure
This indicator is for chart analysis and market context only. It does not provide investment advice, trading advice, or guaranteed outcomes.
All indicators simplify market behavior. This script is no exception. Markets can ignore previously important value references, react differently across symbols and timeframes, and change behavior as volatility regimes shift.
Users are responsible for their own confirmation process, execution decisions, and risk management. 지표

Double Edge VP🔷 Double Edge VP
━━━━━━━━━━━━━━━━━━━
Two institutional-grade tools. One indicator. Zero compromise.
This script brings together a dynamic Visible Range Volume Profile and a
non-repainting Double Bottom / Double Top pattern detector into a single
seamless overlay.
If you trade with volume context and price action structure together, this
is the only indicator you need on your chart.
─────────────────────────────────────────────────────────────
🔹 MODULE 1 — VISIBLE RANGE VOLUME PROFILE (VRVP)
─────────────────────────────────────────────────────────────
Most volume profiles are anchored to a fixed session or a manually selected
range. This one is different. The VRVP dynamically recalculates on every
incoming tick based on the exact bars currently visible on your screen.
Scroll left. Zoom in. Zoom out. The profile instantly rebuilds itself to
show the volume distribution for whatever price range you are looking at.
This is how professional traders use volume — not locked to a calendar
session, but alive and responsive to the context they are analyzing.
📌 Point of Control (POC)
The price row with the highest traded volume across the entire visible range.
This is the most accepted price level — the market's center of gravity.
Displayed as a bold golden dashed line spanning the full visible range with
a price label on the right edge. Price has a strong tendency to return to
the POC after extended moves away from it.
📌 Value Area — VAH & VAL
The zone containing 70% of all volume traded in the visible range (percentage
is fully adjustable). Based on the standard Auction Market Theory convention
used by professional futures and equity traders worldwide.
• Price trading inside the Value Area = fair value, expect rotation
• Price trading outside the Value Area = potential imbalance and opportunity
VAH and VAL are rendered as cyan dashed lines with a semi-transparent fill
between them, making the zone immediately readable at any zoom level.
📌 High Volume Nodes (HVN)
Rows where volume is at or above a configurable threshold relative to the POC
(default 75%). These are areas where the market spent significant time and
accepted price — they act as strong support and resistance levels. Price
frequently slows down, consolidates, or reverses at HVNs. Highlighted in teal.
📌 Low Volume Nodes (LVN)
Rows where volume is at or below a configurable threshold relative to the POC
(default 20%). These are price inefficiency zones — areas the market moved
through quickly with minimal acceptance. Price tends to travel rapidly through
LVNs in both directions and often returns to fill them later. Highlighted in red.
📌 Bull / Bear Volume Split
Every profile row is colored by directional dominance — green when buyer-
initiated volume exceeds seller-initiated, red when the opposite is true.
This gives you immediate insight into who controlled each price level, not
just how much volume traded there.
📌 Volume Labels Inside Every Bar
Each profile row displays its actual volume quantity directly inside the bar
itself — for example: 13.926K, 437, 2.8K. This is rendered using Pine
Script's box text parameter rather than label objects, which means every
single row is labeled regardless of Pine's 50-label hard cap. No rows are
ever skipped or silently dropped.
📌 Net Delta Box
The row with the largest absolute imbalance between buyer and seller volume
receives a standalone colored overlay showing the signed delta value —
for example -142 or +3.2K. Red background indicates net selling pressure.
Green background indicates net buying pressure. This single number tells
you where the market's sharpest directional commitment occurred.
─────────────────────────────────────────────────────────────
🔹 MODULE 2 — DOUBLE BOTTOM & DOUBLE TOP DETECTOR (DB/DT)
─────────────────────────────────────────────────────────────
Double Bottoms and Double Tops are among the most reliable reversal patterns
in technical analysis — but most detectors repaint, trigger too early, or
draw signals before the pattern is actually confirmed. This one does not.
Every signal in this detector is generated only after three conditions are
simultaneously true:
1. Two comparable pivot lows (or highs) have been confirmed with full
symmetric lookback on both sides — meaning the pivot cannot be detected
until the required number of bars has passed after it.
2. The price difference between the two pivots falls within your defined
tolerance threshold, ensuring genuine structural similarity.
3. The neckline has been broken by a configurable number of consecutive
bar closes in the signal direction — filtering out wicks, spikes, and
intra-bar noise that would otherwise produce false entries.
Once all three conditions are met, the signal is final and will never be
removed or moved to a different bar.
📌 Double Bottom — Bullish Reversal
Detects two pivot lows of similar price within a configurable bar window.
The neckline is automatically set to the highest high between the two bottoms.
A Long signal fires after the required number of consecutive closes above
the neckline. The indicator draws the "W" pattern connectors, DB labels at
both pivot points, a Long ↗ entry label, and the TP level line.
📌 Double Top — Bearish Reversal
Mirror logic of the Double Bottom. Two pivot highs of similar price within
the bar window. The neckline is the lowest low between the two tops. A Short
signal fires after consecutive closes below the neckline. Draws the "M"
pattern connectors, DT labels, a Short ↘ entry label, and the TP level line.
📌 7 TP / SL Calculation Modes
Choose the method that fits your trading style:
Bottom-to-Neckline → TP projected by the full pattern height (classic AMT)
R/R Ratio → Fixed reward-to-risk multiple, e.g. 2:1 or 3:1
ATR → Levels scaled dynamically by Average True Range
Percent → Fixed percentage distance from entry price
Points → Fixed point distance using syminfo.mintick
Pips → Fixed pip distance for forex instruments
Ticks → Fixed tick distance for futures instruments
📌 Trailing Stop Loss
When enabled, the stop loss moves in the direction of the trade as price
moves favorably, locking in profit while never widening risk. The trail
distance is fixed as the original entry-to-SL gap so your initial risk
profile is always preserved.
📌 TP Visual — Offset Dotted Line
The Take Profit level is displayed as a two-part line: a faint dotted
connector from the signal bar leading to a bold dotted TP segment that
begins a configurable number of bars to the right. This keeps the area
directly around the signal bar clean and readable — the same presentation
style used in institutional strategy publications.
─────────────────────────────────────────────────────────────
📊 LIVE STATISTICS TABLE
─────────────────────────────────────────────────────────────
A performance tracking table displays in your chosen screen position and
updates in real time as new patterns are detected across full chart history.
Tracked separately for Double Bottoms and Double Tops:
→ Total patterns detected
→ Trades triggered (neckline-confirmed signals only)
→ TP hits and SL hits (including trailing stop results)
→ Win rate % — color coded green above 50%, red below
→ Bar distance between pattern points: Min / Average / Median / Max
→ Price % difference between pattern points: Min / Average / Median / Max
Table position is fully configurable: Bottom Right, Bottom Left, Top Right,
Top Left, Middle Right, or Middle Left.
─────────────────────────────────────────────────────────────
🔔 ALERTS
─────────────────────────────────────────────────────────────
Two alert conditions fire on bar close — one for Long signals (Double Bottom
confirmed) and one for Short signals (Double Top confirmed).
Both messages are fully customizable and include the standard TradingView
dynamic placeholders {{ticker}}, {{interval}}, and {{close}} .
─────────────────────────────────────────────────────────────
⚙️ SETTINGS AT A GLANCE
─────────────────────────────────────────────────────────────
All inputs are organized into clearly labeled groups in the settings panel:
Profile → Rows, Value Area %, HVN threshold, LVN threshold
Visual → Profile width, POC / VA / fill / text / delta toggles
Colors → Full color control for every profile element
Detection → Pivot length, bar range, % tolerance, confirm bars,
enable/disable DB and DT independently
TP/SL → Mode selector, ATR settings, % / Points / Pips inputs,
trailing stop toggle, TP line offset and length
Visual → Colors for dots, necklines, signals, pattern lines,
label size, dot size, show/hide toggles
Table → Show/hide, position, text size
Alerts → Custom long and short alert message text
─────────────────────────────────────────────────────────────
📐 TECHNICAL TRANSPARENCY
─────────────────────────────────────────────────────────────
• max_boxes_count = 500 | max_lines_count = 500 | max_labels_count = 500
• VRVP runs only on barstate.islast — profile boxes are cleared and rebuilt
every tick using pooled drawing arrays
• DB/DT runs every bar using individually named persistent var handles —
the two modules share zero drawing objects
• Volume labels use box.new(text=...) to bypass the 50-label hard cap
• All DB/DT signals are strictly non-repainting — confirmed on bar close only
• Trailing stop ratchets forward only, never widens, preserves original risk
─────────────────────────────────────────────────────────────
📌 RECOMMENDED USE
─────────────────────────────────────────────────────────────
This indicator is designed for traders who combine volume analysis with price
action structure. The VRVP provides the context — where volume was accepted,
where it was rejected, and what the market considers fair value right now.
The DB/DT detector provides the trigger — confirmed structural reversals at
levels where the volume profile gives you a reason to act.
Best suited for:
→ Liquid instruments with reliable volume data
(Equities, Futures, Crypto spot markets)
→ Intraday and swing timeframes (1m through Daily)
→ Traders familiar with Auction Market Theory
→ Traders who want pattern detection without repainting
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Use the VRVP to understand where the market has been.
Use the DB/DT detector to anticipate where it is going next.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Disclaimer: This indicator is for educational purposes only. Always practice proper risk management and combine with your own analysis before making trading decisions. Happy trading. 지표

Liquidity Structure & Order Flow [UAlgo]Liquidity Structure & Order Flow is a range based market participation tool that combines a custom volume profile, value area analysis, liquidity void detection, and unusual volume tagging into a single chart overlay. Its goal is to show not only where volume has concentrated across price, but also how that activity was distributed between estimated buying pressure and selling pressure inside the recent market structure.
The script begins by scanning a rolling lookback range, then divides that vertical price space into a configurable number of bins. Each bin becomes a price segment that stores estimated buy volume, sell volume, and total volume. From there, the script builds a profile that highlights the Point of Control, the value area, and the internal order flow balance across the studied range.
What makes this indicator especially useful is that it does more than draw a standard profile. It also identifies areas where participation is abnormally thin relative to both the Point of Control and local neighboring bins. These low participation areas are marked as liquidity voids, helping the user see where the market moved through price with relatively little acceptance.
In addition, the script monitors the current bar for unusually large activity using a volume z score and a directional delta ratio filter. When a bar shows both exceptional size and meaningful directional imbalance, the script prints a bubble style marker above or below price. This gives the user a way to spot unusual participation events as they happen.
The result is a tool that can be used for profile analysis, liquidity mapping, imbalance recognition, and structural context. It helps answer several practical questions at once: where the market accepted price, where it rejected or skipped through price, where the strongest concentration of activity formed, and whether recent candles are showing exceptional directional participation.
🔹 Features
🔸 Custom Range Based Volume Profile
The script constructs a manual volume profile over the selected lookback period. Instead of relying on a built in profile engine, it divides the recent range into user defined price bins and allocates each bar’s volume into those bins. This gives full control over how the profile is built and how the final distribution is interpreted.
🔸 Buy Volume and Sell Volume Estimation
Every candle contributes both buy side and sell side estimates. The script uses the candle’s open, high, low, and close to derive a buy volume ratio, then splits total volume into buy volume and sell volume accordingly. This creates a practical order flow style approximation that is more informative than total volume alone.
🔸 Proportional Price Overlap Allocation
When a candle spans multiple bins, the script distributes its buy volume, sell volume, and total volume proportionally according to how much of the candle overlaps each bin. This produces a more realistic internal structure than simply dropping the full bar volume into one price row.
🔸 Point of Control Detection
The indicator finds the bin with the highest total volume and marks it as the Point of Control. This gives the user an immediate view of the strongest participation price inside the studied range.
🔸 Value Area Calculation
After the Point of Control is found, the script expands upward and downward through neighboring bins until the selected percentage of total profile volume is captured. This defines Value Area High and Value Area Low, allowing the user to distinguish the central acceptance region from the rest of the range.
🔸 Profile Coloring by Participation Side
The profile is drawn as stacked horizontal boxes showing estimated buy side participation and sell side participation inside each row. Bins inside the value area use stronger coloring, while bins outside the value area use softer coloring. This makes the internal structure easy to read visually.
🔸 Liquidity Void Detection
The script scans for bins with unusually weak participation outside the value area. A bin qualifies as a liquidity void candidate only if it is both small relative to the Point of Control and also weaker than its nearby neighbors. Consecutive weak bins are grouped into a larger void zone and labeled directly on the chart.
🔸 Unusual Volume Bubble Markers
Current bar activity is evaluated using a long period volume average and standard deviation. If the bar’s volume is statistically unusual and its estimated delta ratio is large enough, the script prints a directional bubble marker. Positive directional activity is shown below price, and negative directional activity is shown above price.
🔸 Optional Profile and Void Display
The user can independently control whether the volume profile, liquidity voids, and unusual volume markers are shown. This makes the script flexible enough for both full structure analysis and lighter chart layouts.
🔸 Extendable Structural Levels
The Point of Control, Value Area High, and Value Area Low can be drawn as either compact structure references or extended lines, depending on the chosen setting. This allows the user to decide whether the levels should function as local annotations or ongoing chart references.
🔸 Useful for Acceptance and Imbalance Analysis
The combination of profile structure, value area, void zones, and unusual activity markers gives the indicator a broader purpose than a standard profile. It can help identify accepted price, skipped price, directional participation, and possible future reaction areas.
🔹 Calculations
1) Building the Volume Profile Container
type PriceBin
float price
float buyVol = 0.0
float sellVol = 0.0
float totalVol = 0.0
type VolumeProfile
float highPrice = na
float lowPrice = na
float binSize = na
array bins
float pocPrice = na
float pocVol = 0.0
float vah = na
float val = na
float totalVol = 0.0
This is the foundation of the whole script.
Each PriceBin stores one price level area inside the profile. It contains:
the row midpoint price,
estimated buy volume,
estimated sell volume,
and total volume.
The VolumeProfile structure stores the full profile state:
the highest price of the lookback range,
the lowest price of the lookback range,
the bin size,
the array of bins,
and the final analytical values such as Point of Control, Value Area High, Value Area Low, and total profile volume.
So before any analysis happens, the script defines a complete custom data model for price distribution and order flow style estimation.
2) Initializing the Bins Across the Lookback Range
method initBins(VolumeProfile this, float h, float l, int numBins) =>
this.highPrice := h
this.lowPrice := l
this.binSize := (h - l) / numBins
this.pocPrice := na
this.pocVol := 0.0
this.totalVol := 0.0
this.vah := na
this.val := na
this.bins := array.new()
for i = 0 to numBins - 1
this.bins.push(PriceBin.new(price = l + i * this.binSize + (this.binSize / 2)))
This method creates the working profile rows.
First, it stores the high and low of the selected lookback period. Then it calculates binSize , which is the vertical price height of each row. That is simply the full range height divided by the number of bins.
After resetting all major profile outputs, the script creates a fresh bin array. Each new bin is assigned a midpoint price:
l + i * this.binSize + (this.binSize / 2)
That midpoint becomes the visual and analytical center of the row.
In practical terms, this is where the script transforms the raw market range into a structured ladder of price rows that can later receive allocated volume.
3) Locating the Correct Bin for a Price
method getBinIndex(VolumeProfile this, float p) =>
if na(this.lowPrice) or na(this.binSize) or this.binSize == 0
0
else
int idx = math.floor((p - this.lowPrice) / this.binSize)
math.max(0, math.min(idx, this.bins.size() - 1))
This helper method maps any price to its correct row index inside the profile.
It works by measuring how far the price sits above the profile low, then dividing that distance by the bin size. The result is the raw row index. After that, the value is clamped so it always stays inside the valid bin range.
This is important because the script repeatedly needs to know which rows are touched by each candle’s low and high. Without this mapping step, the profile could not distribute volume across price space correctly.
4) Estimating Buy Volume and Sell Volume From Candle Structure
float hlR = high - low
float bVR = hlR == 0 ? 0.5 : (close - low + high - open) / (2 * hlR)
float currentBuyVol = volume * bVR
float currentSellVol = volume * (1 - bVR)
float delta = currentBuyVol - currentSellVol
This snippet explains how the script approximates order flow direction on the current bar.
First, it measures the candle range from high to low. Then it computes a buy volume ratio using the relative location of the open and close inside that range:
(close - low + high - open) / (2 * hlR)
This ratio becomes a practical estimate of how much of the bar’s total volume behaved like buying pressure versus selling pressure. If the candle closes stronger and opens higher inside its range, the ratio leans more bullish. If the candle structure is weaker, the ratio leans more bearish.
That ratio is then used to split total volume into:
currentBuyVol
and
currentSellVol
Finally, the script calculates delta as the difference between estimated buy volume and estimated sell volume.
This is not true transaction tagged exchange delta, but it is a useful chart based directional participation model.
5) Distributing Candle Volume Across Touched Price Rows
method addBarVolume(VolumeProfile this, float h, float l, float c, float o, float v) =>
float hlRange = h - l
float buyVolRatio = hlRange == 0 ? 0.5 : (c - l + h - o) / (2 * hlRange)
float buyV = v * buyVolRatio
float sellV = v * (1 - buyVolRatio)
int startIdx = this.getBinIndex(l)
int endIdx = this.getBinIndex(h)
for i = startIdx to endIdx
if i >= 0 and i < this.bins.size()
PriceBin b = this.bins.get(i)
float binTop = b.price + (this.binSize / 2)
float binBot = b.price - (this.binSize / 2)
float overlapTop = math.min(h, binTop)
float overlapBot = math.max(l, binBot)
float overlap = math.max(0.0, overlapTop - overlapBot)
float weight = hlRange > 0 ? overlap / hlRange : (1.0 / (endIdx - startIdx + 1))
b.buyVol += buyV * weight
b.sellVol += sellV * weight
b.totalVol += v * weight
this.bins.set(i, b)
this.totalVol += v * weight
This is one of the most important calculations in the entire script.
For each candle inside the lookback period, the script first computes estimated buy volume and sell volume. Then it finds which profile rows are touched by the candle’s low and high.
For every touched row, it measures how much of the candle overlaps that specific row. That overlap becomes a weighting factor:
weight = overlap / hlRange
If a candle overlaps a row heavily, that row receives a larger share of the bar’s volume. If the overlap is small, the row receives only a small share.
The script then adds weighted buy volume, weighted sell volume, and weighted total volume into that bin.
This is much more realistic than assigning all volume to a single row because it respects the actual price space the candle traveled through.
6) Determining the Point of Control
method calcValueArea(VolumeProfile this, float pct) =>
float midPrice = (this.highPrice + this.lowPrice) / 2
float maxVol = -1.0
float bestPrice = na
int pocIdx = -1
for i = 0 to this.bins.size() - 1
PriceBin b = this.bins.get(i)
if b.totalVol > maxVol
maxVol := b.totalVol
bestPrice := b.price
pocIdx := i
else if b.totalVol == maxVol and maxVol > 0
if math.abs(b.price - midPrice) < math.abs(bestPrice - midPrice)
bestPrice := b.price
pocIdx := i
this.pocVol := maxVol
this.pocPrice := bestPrice
This is the first phase of the value area calculation.
The script scans all bins and finds the row with the greatest total volume. That row becomes the Point of Control. If two rows have the same maximum volume, the script breaks the tie by choosing the one closer to the middle of the full lookback range.
That tie handling matters because it avoids unstable selection when multiple bins have identical strength.
After the winning row is found, the script stores:
the Point of Control volume in pocVol
and the Point of Control price in pocPrice
So the Point of Control is not simply a visual midpoint. It is the actual strongest participation row in the profile.
7) Expanding Upward and Downward to Build the Value Area
float targetVol = this.totalVol * pct / 100.0
float currentVol = 0.0
if pocIdx >= 0 and pocIdx < this.bins.size()
currentVol := this.bins.get(pocIdx).totalVol
int upIdx = pocIdx + 1
int dnIdx = pocIdx - 1
while currentVol < targetVol and (upIdx < this.bins.size() or dnIdx >= 0)
float upVol = upIdx < this.bins.size() ? this.bins.get(upIdx).totalVol : -1.0
float dnVol = dnIdx >= 0 ? this.bins.get(dnIdx).totalVol : -1.0
After finding the Point of Control, the script calculates the target volume required for the value area. For example, if the input is 70 percent, the target becomes 70 percent of total profile volume.
The expansion begins from the Point of Control row itself. currentVol starts with the Point of Control row’s own total volume. Then the script looks one row up and one row down, repeatedly expanding until the accumulated volume reaches the target.
This is the standard logic of building a value area around the strongest participation center.
8) Deciding Whether to Expand Up or Down
if upVol > dnVol and upVol != -1.0
currentVol += upVol
upIdx += 1
else if dnVol > upVol and dnVol != -1.0
currentVol += dnVol
dnIdx -= 1
else if upVol == dnVol and upVol != -1.0
if currentVol + upVol > targetVol
if math.abs(this.bins.get(upIdx).price - midPrice) < math.abs(this.bins.get(dnIdx).price - midPrice)
currentVol += upVol
upIdx += 1
else
currentVol += dnVol
dnIdx -= 1
else
currentVol += upVol + dnVol
upIdx += 1
dnIdx -= 1
This block decides which side to include next in the value area.
If the row above has more volume than the row below, the script expands upward. If the row below has more volume, it expands downward. If both sides are equal, it uses distance to the overall midpoint as a tie breaker when necessary.
This is important because value area growth should follow participation strength, not arbitrary direction. The final result is a value area that naturally wraps around the highest volume concentration.
9) Final VAH and VAL Assignment
int finalUpIdx = math.max(pocIdx, upIdx - 1)
int finalDnIdx = math.min(pocIdx, dnIdx + 1)
this.vah := finalUpIdx < this.bins.size() ? this.bins.get(finalUpIdx).price : this.highPrice
this.val := finalDnIdx >= 0 ? this.bins.get(finalDnIdx).price : this.lowPrice
Once expansion is complete, the script converts the final included rows into value area boundaries.
The highest included row becomes Value Area High.
The lowest included row becomes Value Area Low.
These values define the central price zone where the chosen percentage of the profile’s total volume was traded.
So VAH and VAL are directly derived from the row by row structure of the profile, not from any fixed percentage of price range.
10) Detecting Unusual Volume Activity
float volSma = ta.sma(volume, 200)
float volStdev = ta.stdev(volume, 200)
float zScore = volStdev == 0 ? 0 : (volume - volSma) / volStdev
float deltaRatio = volume > 0 ? math.abs(delta) / volume : 0
bool isUnusual = zScore > zScoreThreshold and deltaRatio >= deltaRatioThreshold
This block evaluates whether the current bar is unusually active.
First, the script computes a 200 period average volume and standard deviation. Then it transforms the current bar’s volume into a z score, which shows how many standard deviations the bar stands above normal background activity.
Next, it calculates deltaRatio , which measures how large the directional imbalance is relative to total volume.
A bar is marked unusual only if both conditions are true:
the volume is statistically large enough,
and the directional imbalance is meaningful enough.
This double filter helps reduce false signals from large but directionless bars.
11) Printing Unusual Volume Bubbles
if showUnusual and isUnusual
string lblText = (delta > 0 ? "🟢 " : "🔴 ") + str.tostring(math.round(volume))
color lblColor = delta > 0 ? color.new(color.green, 0) : color.new(color.red, 0)
label uLbl = label.new(bar_index, delta > 0 ? low : high, text=lblText, style=label.style_none, textcolor=lblColor, yloc=delta > 0 ? yloc.belowbar : yloc.abovebar, size=size.small)
When an unusual bar is detected, the script prints a directional marker.
If estimated delta is positive, the bubble is shown below price in green.
If estimated delta is negative, the bubble is shown above price in red.
The displayed text also includes the rounded volume value. This allows the user to quickly see both direction and size of the unusual participation event.
So these markers are not random momentum tags. They specifically highlight bars where both participation size and directional imbalance stand out.
12) Rebuilding the Profile on the Last Bar
float highestPrice = ta.highest(high, lookback)
float lowestPrice = ta.lowest(low, lookback)
if barstate.islast and bar_index >= lookback - 1
profile.initBins(highestPrice, lowestPrice, rows)
for i = 0 to lookback - 1
profile.addBarVolume(high , low , close , open , volume )
profile.calcValueArea(vaPct)
This is the main execution block for the profile.
First, the script finds the highest high and lowest low across the chosen lookback window. That defines the total vertical space of the analysis.
Then, on the last visible bar, it:
initializes the bins,
loops through every candle inside the lookback,
adds each candle’s weighted volume into the profile,
and finally calculates the value area.
Running this only on the last bar is efficient because the full profile is a visual structure based on the current lookback window. It does not need to be redrawn historically on every past bar.
13) Scaling and Drawing the Profile Histogram
float maxVol = profile.pocVol
float allVols = array.new_float()
for i = 0 to profile.bins.size() - 1
allVols.push(profile.bins.get(i).totalVol)
float avgVol = allVols.avg()
float stdVol = allVols.stdev()
float clampedMaxVol = math.max(math.min(maxVol, avgVol + (stdVol * 2)), 0.000001)
Before drawing the profile, the script prepares a safer scaling reference.
Instead of using raw Point of Control volume alone without adjustment, it clamps the maximum drawable scale using the average row volume plus two standard deviations. This helps prevent a single extreme row from making the rest of the profile look too compressed.
In practical terms, this means the visual histogram remains readable even when one row is exceptionally dominant.
14) Drawing Buy Side and Sell Side Inside Each Row
int buyLen = math.round((b.buyVol / b.totalVol) * (drawVol / clampedMaxVol) * profileWidth)
int sellLen = math.round((b.sellVol / b.totalVol) * (drawVol / clampedMaxVol) * profileWidth)
bool inVA = b.price <= profile.vah and b.price >= profile.val
bool isPocRow = math.abs(b.price - profile.pocPrice) <= profile.binSize * 0.5
int x1 = profileRight
int x2 = x1 - buyLen
if buyLen > 0
box bB = box.new(x1, topP, x2, botP, border_color=c_border, bgcolor=c_buy)
int x3 = x2
int x4 = x3 - sellLen
if sellLen > 0
box bS = box.new(x3, topP, x4, botP, border_color=c_border, bgcolor=c_sell)
This is the actual profile drawing logic.
For each row, the script determines how much of the row’s total activity came from estimated buy volume and how much came from estimated sell volume. It then converts those fractions into horizontal lengths.
The buy portion is drawn first, then the sell portion continues from the end of the buy section. This creates a stacked horizontal bar that reveals both total participation and internal directional composition.
The row also receives context coloring:
rows inside the value area use stronger color treatment,
and the Point of Control row can receive a distinct border.
So the histogram communicates three layers at once:
how much volume was traded there,
whether that row sits inside the value area,
and how that row’s activity was split between estimated buying and selling pressure.
15) Drawing POC, VAH, and VAL Lines
line pocL = line.new(lineStartX, profile.pocPrice, lineEndX, profile.pocPrice, color=col_poc, width=2, style=line.style_solid)
profileLines.push(pocL)
line vahL = line.new(lineStartX, profile.vah, lineEndX, profile.vah, color=col_vah, width=1, style=line.style_dashed)
profileLines.push(vahL)
line valL = line.new(lineStartX, profile.val, lineEndX, profile.val, color=col_val, width=1, style=line.style_dashed)
profileLines.push(valL)
Once the profile is built, the script draws the three most important structural references:
Point of Control,
Value Area High,
and Value Area Low.
These lines can behave as compact annotations near the profile or as broader structure references if extension is enabled.
This gives the user a quick way to read acceptance and central balance without needing to inspect every row manually.
16) Detecting Liquidity Voids
float voidLimit = profile.pocVol * (voidThreshold / 100.0)
bool inVoid = false
float voidStartPrice = na
for i = 0 to profile.bins.size() - 1
PriceBin b = profile.bins.get(i)
bool isOutsideVA = b.price > profile.vah or b.price < profile.val
This is the beginning of the liquidity void logic.
A row is never treated as a void candidate solely because its volume is small. The script first requires that the row be outside the value area. This matters because low volume inside the main acceptance zone does not carry the same meaning as low volume outside it.
The script also calculates voidLimit as a percentage of Point of Control volume. That creates a relative participation threshold tied to the strongest row in the profile.
17) Comparing Each Row to Its Neighbors
float sumNeighbors = 0.0
int nC = 0
for j = math.max(0, i - 2) to math.min(profile.bins.size() - 1, i + 2)
if j != i
sumNeighbors += profile.bins.get(j).totalVol
nC += 1
float localAvg = nC > 0 ? sumNeighbors / nC : 0.0
bool isGap = b.totalVol < (localAvg * 0.5)
bool isLowVol = b.totalVol < voidLimit
bool isVoid = isLowVol and isGap and isOutsideVA
This is the real filter that defines a liquidity void.
The script looks at nearby bins around the current row and calculates a local neighbor average. Then it applies two separate tests:
the row must be low relative to the Point of Control threshold,
and it must also be weak relative to its nearby neighbors.
Only if both are true, and the row is outside the value area, does the script classify it as a void.
This is important because it prevents the indicator from marking every low volume row as a void. A valid void must look weak both globally and locally.
18) Grouping Consecutive Void Rows Into Zones
if isVoid
if not inVoid
inVoid := true
voidStartPrice := b.price - (profile.binSize / 2)
else
if inVoid
inVoid := false
float voidEndPrice = b.price - (profile.binSize / 2)
float topCoord = math.max(voidStartPrice, voidEndPrice)
float botCoord = math.min(voidStartPrice, voidEndPrice)
box vBox = box.new(bar_index - lookback, topCoord, bar_index, botCoord, border_color=na, bgcolor=col_void)
Once a void row is detected, the script begins tracking a continuous void run. If the next row is also a void, the zone continues. When the run ends, the script closes the zone and draws a box covering the full void area.
This means the indicator does not plot isolated tiny marks for each row. Instead, it groups neighboring weak rows into a cleaner structure that better represents a meaningful liquidity gap.
That box is then labeled as a liquidity void, making the zone easy to identify visually. 지표

Range Finder & Profile [UAlgo]Range Finder & Profile is a structured market range detection tool that combines pivot based range discovery with an embedded volume profile. Its purpose is to identify areas where price begins to rotate inside a defined boundary, track whether that balance remains intact, and then summarize how volume was distributed inside the completed range once price finally exits it.
The script starts by using pivot highs and pivot lows to define potential horizontal boundaries. When a valid upper and lower reference exist, and price is trading inside those bounds without already breaking them, the script opens a candidate range. From that point onward, it keeps monitoring the structure bar by bar, checking whether the range survives long enough to become confirmed and whether price remains accepted inside it.
What makes this indicator especially useful is that it does not stop at simply drawing a box around consolidation. Once a range becomes confirmed, it also builds a row based internal profile of all activity inside that zone. When the range eventually breaks, the script calculates Point of Control, Value Area High, and Value Area Low, then draws a compact profile directly inside the range. This transforms a simple horizontal box into a more informative market acceptance map.
The result is a tool that can help traders study balance, distribution, and eventual expansion. It is useful for identifying clean consolidation structures, understanding where the heaviest participation occurred inside a range, and interpreting whether the breakout happened after meaningful internal acceptance or after a less developed structure.
🔹 Features
🔸 Pivot Based Range Discovery
The script uses pivot highs and pivot lows to establish potential range boundaries. This creates a structure that reacts to meaningful swing points rather than arbitrary rolling highs and lows. As a result, the detected ranges tend to reflect actual market rotation more naturally.
🔸 Clean Range Validation
A new range is only created when price is already trading inside the proposed top and bottom boundaries and when no bar in the candidate history has already closed outside those levels. This helps prevent invalid or already broken ranges from being accepted.
🔸 Overlap Protection
The script tracks where the last completed range ended and avoids creating a new one that starts inside an already closed structure. This reduces repeated overlap and keeps the chart cleaner.
🔸 Minimum Range Confirmation
Not every detected range is immediately treated as valid. The structure must survive for a minimum number of bars before it becomes confirmed. This helps filter out weak or short lived consolidations.
🔸 Embedded Volume Profile
Each confirmed range contains its own internal volume profile. The vertical height of the range is divided into configurable rows, and every bar contributes volume into the relevant price segments. This creates a compact distribution map inside the actual range boundaries.
🔸 Proportional Volume Allocation
The script does not simply drop full bar volume into a single row unless the bar has no height. Instead, when a candle spans multiple rows, its volume is distributed proportionally across the overlapped sections. This produces a more realistic representation of participation across the range.
🔸 Point of Control Detection
After the range is complete, the script finds the profile row with the highest accumulated volume. This row becomes the Point of Control, giving the user a quick view of the price area with the strongest concentration of activity.
🔸 Value Area Calculation
The script expands outward from the Point of Control and accumulates neighboring rows until the selected percentage of total range volume is reached. This produces Value Area High and Value Area Low, which highlight the area where most participation occurred.
🔸 Gradient Range Background
The active and completed range is drawn with a multi slice background gradient between the upper and lower colors. This improves readability and gives the zone a more polished visual structure.
🔸 Histogram Inside the Range
When a range is confirmed and completed, the script draws horizontal histogram bars inside the zone. Rows inside the value area use a dedicated color, while rows outside the value area use a separate profile color. This makes internal acceptance easy to read visually.
🔸 Live Active Range Updates
While the range is still active and not yet broken, the background extends forward in time with every new bar. Once the range becomes confirmed, profile and value area calculations are refreshed continuously until the breakout occurs.
🔸 Practical Market Structure Use
This makes the indicator useful for consolidation analysis, acceptance and rejection studies, and breakout context. A trader can see not only where price paused, but also how volume built inside that pause before expansion occurred.
🔹 Calculations
1) Pivot Detection for Range Anchors
float ph = ta.pivothigh(high, lengthInput, lengthInput)
float pl = ta.pivotlow(low, lengthInput, lengthInput)
if not na(ph)
recentPH := ph
recentPHIndex := bar_index
if not na(pl)
recentPL := pl
recentPLIndex := bar_index
This is the starting point of the whole script.
The code asks TradingView to detect a pivot high and a pivot low using the selected swing length. A pivot high appears only after enough bars have formed on both sides of the swing, and the same logic applies to a pivot low. Because of that, pivots are confirmed reference points rather than instant highs or lows.
When a valid pivot high is found, the script stores two things.
The pivot price itself in recentPH
The bar index where that pivot actually occurred in recentPHIndex
The same is done for pivot lows through recentPL and recentPLIndex .
This means the script always keeps track of the latest confirmed upper swing and the latest confirmed lower swing. Those two swing references become the raw ingredients for a possible trading range.
2) Candidate Range Creation Logic
bool canCreateRange = na(activeRange) and not na(recentPH) and not na(recentPL)
if canCreateRange
float top = math.max(recentPH, recentPL)
float bot = math.min(recentPH, recentPL)
if top > bot and close <= top and close >= bot
int sIndex = math.min(recentPHIndex, recentPLIndex)
int barsBack = bar_index - sIndex
This block decides whether the script is even allowed to start a new range.
First, canCreateRange requires three conditions:
there must be no currently active range,
there must be a recent pivot high,
and there must be a recent pivot low.
If those conditions are met, the script builds a provisional upper bound and lower bound using the greater and smaller of the two pivot prices. Then it checks whether current price is actually inside that proposed range. This is important because it prevents the script from creating a range that price has already escaped.
The code also finds sIndex , which is the earlier of the two pivot bar indices. That earlier point becomes the true starting location of the range. Then barsBack measures how many bars ago the range began.
So at this stage, the script has a full candidate structure:
an upper price,
a lower price,
and a starting point in time.
3) Overlap Prevention and Broken History Check
bool isOverlapping = false
if sIndex <= lastClosedRangeEndIndex
isOverlapping := true
if not isOverlapping
bool broken = false
if barsBack > 0
for i = 0 to barsBack
if close > top or close < bot
broken := true
break
This section filters out bad candidates before a range is created.
First, the script checks whether the proposed start index falls inside or before the end of the last completed range. If it does, the new candidate is marked as overlapping and rejected. This keeps the indicator from repeatedly generating new boxes on top of old structures.
Next, even if there is no overlap, the script scans every bar from the proposed start point up to the present. It checks whether any close moved above the top boundary or below the bottom boundary. If that happened, the candidate is marked as broken.
This is a very important quality filter. It means the script does not simply connect two pivots and call that a range. It also verifies that price actually stayed accepted inside those boundaries over the full candidate history.
4) Initializing the Range Object
activeRange := RangeData.new(
startIndex = sIndex,
startTime = time ,
endIndex = bar_index,
endTime = time,
topPrice = top,
bottomPrice = bot,
isActive = true,
isConfirmed = false,
totalVolume = 0.0,
pocPrice = na, pocVolume = 0.0, pocIndex = -1, vah = na, val = na,
bgBoxes = na, histBoxes = na, pocLine = na, vahLine = na, valLine = na, pocLabel = na, vahLabel = na, valLabel = na
)
activeRange.initProfile(profileRows)
Once the script is satisfied that the candidate is valid, it creates a new RangeData object.
This object stores all important information about the range:
where it starts,
where it currently ends,
its top price,
its bottom price,
whether it is still active,
whether it is confirmed,
and all profile related values such as total volume, Point of Control, Value Area High, and Value Area Low.
Immediately after creating the object, the script calls initProfile(profileRows) . That method prepares the internal volume profile rows that will later hold the distribution data.
So this is the moment where the script moves from pure detection into active tracking.
5) Building the Internal Profile Rows
method initProfile(RangeData this, int rowsCount) =>
float step = (this.topPrice - this.bottomPrice) / rowsCount
this.profile := array.new()
for i = 0 to rowsCount - 1
float pBottom = this.bottomPrice + (i * step)
float pTop = pBottom + step
this.profile.push(ProfileRow.new(pTop, pBottom, 0.0))
This method divides the height of the range into a fixed number of rows.
First, it calculates step , which is the height of one profile row. That is simply the total range height divided by the selected number of profile rows.
Then it creates an empty profile array and fills it row by row. Each row stores:
its upper price,
its lower price,
and the total volume accumulated in that row.
At this moment, every row starts with zero volume. The profile is just an empty framework waiting to receive bar by bar contributions.
This design is important because the script is not using a prebuilt TradingView volume profile function. It is constructing the profile manually, row by row, inside the exact range boundaries.
6) Adding Volume Into the Profile
method addVolume(RangeData this, float bHigh, float bLow, float bVol) =>
float overlapHigh = math.min(bHigh, this.topPrice)
float overlapLow = math.max(bLow, this.bottomPrice)
if bHigh == bLow and bHigh <= this.topPrice and bHigh >= this.bottomPrice
for i = 0 to this.profile.size() - 1
ProfileRow row = this.profile.get(i)
if bHigh >= row.priceBottom and bHigh <= row.priceTop
row.volumeTotal += bVol
this.totalVolume += bVol
break
else if overlapHigh > overlapLow
float overlapHeight = overlapHigh - overlapLow
float totalHeight = bHigh - bLow
float effectiveVol = totalHeight > 0 ? bVol * (overlapHeight / totalHeight) : bVol
for i = 0 to this.profile.size() - 1
ProfileRow row = this.profile.get(i)
float rowOverlapHigh = math.min(overlapHigh, row.priceTop)
float rowOverlapLow = math.max(overlapLow, row.priceBottom)
if rowOverlapHigh > rowOverlapLow
float rowOverlapHeight = rowOverlapHigh - rowOverlapLow
float rowRatio = rowOverlapHeight / overlapHeight
float addedVol = effectiveVol * rowRatio
row.volumeTotal += addedVol
this.totalVolume += addedVol
This is one of the most important calculations in the whole script.
The goal here is to take a candle and distribute its volume into the profile rows that the candle actually overlaps.
First, the script limits the candle to the range boundaries using overlapHigh and overlapLow . This ensures that only the part of the candle inside the range contributes to the profile.
Then two cases are handled.
If the candle has no height, meaning bHigh == bLow , the full volume is assigned to the single row that contains that exact price.
If the candle does have height, the script calculates how much of the candle actually overlaps the range. That overlapping height becomes the valid section for profile allocation. Then, for each profile row, the script measures how much of that valid section overlaps the row. Volume is distributed proportionally according to that overlap share.
This is much more accurate than placing the full candle volume into a single row. It means tall candles contribute volume across the price levels they truly passed through, which creates a more realistic internal distribution.
7) Filling the New Range With Historical Volume
if barsBack >= 0
for i = 0 to barsBack
float bVol = na(volume ) ? 1.0 : volume
activeRange.addVolume(high , low , bVol)
Right after a new range is created, the script goes back through all bars that belong to that range from its start until the current bar.
For each of those bars, it reads the volume and sends the bar high, bar low, and volume into addVolume .
This step is essential because it backfills the profile immediately. Without it, the range would start with an empty volume profile and would only accumulate data from future bars. Instead, the script reconstructs the whole internal history of the range as soon as the range is created.
Also notice the fallback 1.0 when volume data is missing. That ensures the script can still function on symbols where actual volume may not be available.
8) Range Confirmation and Break Detection
bool isBroken = close > activeRange.topPrice or close < activeRange.bottomPrice
if (bar_index - activeRange.startIndex) >= minRangeLen
activeRange.isConfirmed := true
Once a range is active, the script keeps evaluating two key questions on every bar.
The first question is whether the range is broken.
If the current close moves above the top or below the bottom, the range is considered finished.
The second question is whether the range has lasted long enough to be trusted.
If the number of bars since the range started is at least the user selected minimum, isConfirmed becomes true.
This creates a useful distinction between a candidate range and a confirmed range. A short structure can exist visually for a while, but it only becomes analytically meaningful after it survives long enough.
9) Live Updating While the Range Is Active
if not justCreated
float barVol = na(volume) ? 1.0 : volume
activeRange.addVolume(high, low, barVol)
if activeRange.isConfirmed
activeRange.calcValueArea(valAreaPct)
activeRange.drawProfile(colorBgTop, colorBgBot, colorProfile, colorProfileVA, colorPOC, colorVA)
else
activeRange.updateBgRight(time, colorBgTop, colorBgBot, colorBorder)
This block explains how the range evolves in real time.
If the current bar is not the same bar where the range was created, the script adds the latest candle volume into the profile. That keeps the internal distribution up to date bar by bar.
Then the script behaves differently depending on confirmation state.
If the range is already confirmed, it recalculates the value area and redraws the full profile. This means Point of Control, Value Area High, Value Area Low, and the histogram are all updated continuously as long as price remains inside the range.
If the range is not yet confirmed, the script only extends the background box to the current time. In other words, the market structure is still being monitored, but the full profile is not drawn until the range has proven itself.
10) Point of Control Discovery
float maxVol = -1.0
int pIndex = -1
for i = 0 to this.profile.size() - 1
ProfileRow row = this.profile.get(i)
if row.volumeTotal > maxVol
maxVol := row.volumeTotal
pIndex := i
this.pocIndex := pIndex
this.pocVolume := maxVol
ProfileRow pocRow = this.profile.get(pIndex)
this.pocPrice := (pocRow.priceTop + pocRow.priceBottom) / 2.0
This is the first phase inside the value area calculation.
The script scans every profile row and looks for the one with the largest accumulated volume. That row becomes the Point of Control row.
Once that row is found, the script stores:
the row index in pocIndex ,
the largest row volume in pocVolume ,
and the row midpoint price in pocPrice .
So the Point of Control is not guessed from the center of the range or from price action alone. It is derived directly from the heaviest profile row.
11) Expanding to Build the Value Area
float targetVol = this.totalVolume * (pct / 100.0)
float currentVol = maxVol
int upIndex = pIndex + 1
int downIndex = pIndex - 1
while currentVol < targetVol and (upIndex < this.profile.size() or downIndex >= 0)
float upVol = upIndex < this.profile.size() ? this.profile.get(upIndex).volumeTotal : -1.0
float downVol = downIndex >= 0 ? this.profile.get(downIndex).volumeTotal : -1.0
if upVol == -1.0 and downVol == -1.0
break
Here the script begins with the Point of Control row and tries to accumulate enough neighboring volume to reach the selected percentage of total range volume.
First, it calculates targetVol , which is the amount of total volume required for the value area. For example, if the input is 70 percent, the target is 70 percent of the full profile volume.
The process then starts from the Point of Control row. currentVol begins at the Point of Control volume itself. From there, the script looks one row up and one row down and keeps expanding until the target is reached or no more rows remain.
This is the classic logic of building a value area around the highest participation zone.
12) Choosing Whether to Expand Up or Down
bool addUp = false
if upVol > downVol
addUp := true
else if downVol > upVol
addUp := false
else
int distUp = upIndex - pIndex
int distDown = pIndex - downIndex
if distUp < distDown
addUp := true
else if distDown < distUp
addUp := false
else
addUp := true
This section decides which side should be added next to the value area.
If the row above the current zone has more volume than the row below, the script expands upward.
If the row below has more volume, it expands downward.
If both sides have the same volume, the script breaks the tie by comparing distance from the Point of Control. If distance is also equal, it defaults upward.
This matters because value area construction should not be arbitrary. It should expand toward the heaviest nearby participation first. That keeps the final value area centered around the most meaningful volume concentration.
13) Final VAH and VAL Calculation
int finalUp = math.min(upIndex - 1, this.profile.size() - 1)
int finalDown = math.max(downIndex + 1, 0)
this.vah := this.profile.get(finalUp).priceTop
this.val := this.profile.get(finalDown).priceBottom
After expansion is complete, the script converts the final upper and lower included rows into actual price boundaries.
vah becomes the top of the highest included row.
val becomes the bottom of the lowest included row.
These two values form the value area envelope, showing the price zone that contains the selected percentage of all volume traded inside the range.
So the final value area is not a fixed distance from Point of Control. It adapts to the actual row by row distribution.
14) Drawing the Gradient Range Background
method drawBg(RangeData this, color cBgTop, color cBgBot, color cBorder, int rTime) =>
if not na(this.bgBoxes)
for b in this.bgBoxes
b.delete()
this.bgBoxes := array.new()
int bgSlices = 10
float sliceStep = (this.topPrice - this.bottomPrice) / bgSlices
for i = 0 to bgSlices - 1
float bBot = this.bottomPrice + (i * sliceStep)
float bTop = bBot + sliceStep
this.bgBoxes.push(box.new(this.startTime, bTop, rTime, bBot, border_color=na, bgcolor=sliceCol, xloc=xloc.bar_time))
This method handles the visual background of the range.
Before drawing anything new, the script deletes previously drawn background boxes. Then it splits the range vertically into ten slices. Each slice receives an interpolated color between the selected bottom background color and top background color.
Finally, each slice is drawn as a time based box from the range start to the chosen right edge time.
The result is a smooth vertical color transition across the range body, which makes the zone easier to read and visually separates upper and lower sections.
15) Drawing the Histogram, POC, VAH, and VAL
if this.isConfirmed
float maxVol = this.pocVolume
if maxVol > 0
int rangeTimeWidth = math.max(rightTime - this.startTime, 1000)
int maxTimeWidth = math.round(rangeTimeWidth * 0.35)
for i = 0 to this.profile.size() - 1
ProfileRow row = this.profile.get(i)
if row.volumeTotal > 0
float widthRatio = row.volumeTotal / maxVol
int boxTimeWidth = math.round(maxTimeWidth * widthRatio)
int boxLeftTime = rightTime - boxTimeWidth
bool inVA = (row.priceTop <= this.vah and row.priceBottom >= this.val)
color finalHistCol = inVA ? histVaCol : histCol
this.histBoxes.push(box.new(boxLeftTime, t, rightTime, b, border_color=na, bgcolor=finalHistCol, xloc=xloc.bar_time))
this.pocLine := line.new(this.startTime, this.pocPrice, rightTime, this.pocPrice, color=pocCol, style=line.style_solid, width=2, xloc=xloc.bar_time)
this.vahLine := line.new(this.startTime, this.vah, rightTime, this.vah, color=vaCol, style=line.style_dashed, width=1, xloc=xloc.bar_time)
this.valLine := line.new(this.startTime, this.val, rightTime, this.val, color=vaCol, style=line.style_dashed, width=1, xloc=xloc.bar_time)
This is the drawing engine for the completed profile.
For each row with volume, the script calculates a width ratio relative to the Point of Control volume. Rows with more volume receive wider histogram boxes. Rows with less volume receive narrower boxes.
That width is converted into time space, so the histogram grows leftward from the right edge of the range. This creates a compact in range horizontal profile.
The script also checks whether each row lies inside the value area. If it does, the row uses the value area histogram color. If it does not, it uses the normal profile color. This makes the high participation area visually distinct.
Finally, the script draws three key lines across the full width of the range:
Point of Control,
Value Area High,
and Value Area Low.
These lines convert the internal profile data into easy to read structure references on the chart.
16) What Happens When the Range Breaks
if isBroken
activeRange.isActive := false
activeRange.endIndex := bar_index
activeRange.endTime := time
if not activeRange.isConfirmed
if not na(activeRange.bgBoxes)
for b in activeRange.bgBoxes
b.delete()
else
activeRange.calcValueArea(valAreaPct)
activeRange.drawProfile(colorBgTop, colorBgBot, colorProfile, colorProfileVA, colorPOC, colorVA)
lastClosedRangeEndIndex := bar_index
activeRange := na
This block defines the final lifecycle of a range.
When price closes outside the range boundaries, the active structure is terminated. The script records the ending bar and ending time, then checks whether the range had ever become confirmed.
If the range was never confirmed, its background is deleted and the structure is discarded. This prevents weak or short lived ranges from leaving unnecessary clutter.
If the range was confirmed, the script performs a final value area calculation and profile draw on the completed structure. It also stores the ending index so future ranges do not overlap with this one.
Then the active range is cleared from memory, which allows the script to start searching for the next valid structure. 지표

3D Volume Profile [UAlgo]3D Volume Profile is a chart based volume profile indicator that takes a classic horizontal profile concept and presents it as a pseudo 3D structure directly on price. Instead of drawing flat histogram bars only, the script renders each profile row as a shaded 3D block with a front face, a side face, and a top face, which creates a stronger visual sense of depth and distribution.
The indicator runs on price ( overlay=true ) and builds a rolling volume profile over a user defined lookback window. It divides the recent price range into fixed bins, distributes candle volume across those bins, identifies the Point of Control and the Value Area, and then draws the result on the right side of the chart. Each row is color coded by dominant flow direction, which means the profile can show whether a bin was more buy dominated or sell dominated in addition to showing how much total volume accumulated there.
This makes the tool useful for traders who want more than a basic profile display. It combines:
A rolling horizontal volume profile
Buy versus sell dominance shading
Point of Control and Value Area detection
A forward projected 3D style histogram
Clear POC, VAH, and VAL reference lines on the chart
The final result is a visually rich profile tool designed for fast structural reading, especially when identifying acceptance zones, thin areas, and dominant participation regions.
🔹 Features
🔸 1) Rolling Volume Profile Over a Recent Window
The script builds a rolling profile from the most recent user selected number of bars. This means the profile continuously adapts as new bars come in, making it more useful for current market structure analysis than a fixed session only approach.
🔸 2) 3D Style Histogram Rendering
Each volume row is drawn as a pseudo 3D block rather than a flat rectangle. The script creates:
A front face
A side face
A top face
The side and top faces are shaded versions of the main color, which gives the profile a depth effect and makes the structure easier to read visually.
🔸 3) Customizable 3D Depth in X and Y
The 3D effect is controlled with two settings:
3D Depth X , which controls how far the rear face is shifted horizontally in bars
3D Depth Y , which controls how far the rear face is shifted vertically as a percentage of row height
This allows the user to make the profile look flatter or more pronounced depending on preference.
🔸 4) Buy and Sell Volume Dominance Coloring
Each bin tracks both buy volume and sell volume. If buy volume is greater than or equal to sell volume, the row uses the bullish color. If sell volume dominates, the row uses the bearish color.
This means the profile is not only a measure of total activity. It also adds directional context to each price zone.
🔸 5) Point of Control Detection
The script identifies the row with the highest total volume and marks it as the Point of Control. The POC is highlighted with its own dedicated color and is visually distinct from the rest of the profile.
This gives traders an immediate reference for the most active price zone in the rolling range.
🔸 6) Value Area Calculation
The indicator calculates a Value Area around the Point of Control based on the user selected percentage. Bins inside the Value Area are marked and recolored with the Value Area color, which makes the high participation region easy to identify.
🔸 7) Forward Projected Profile Layout
The profile is drawn to the right of current price using a configurable offset. This keeps the active candle area readable while still placing the profile in a clear and accessible location.
🔸 8) Adjustable Resolution and Width
Users can control:
The lookback length
The number of profile rows
The maximum width of the histogram
The right side offset
This makes the indicator suitable for both coarse structural analysis and more detailed profile inspection.
🔸 9) POC, VAH, and VAL Reference Lines
After the profile is built, the script calculates the POC, Value Area High, and Value Area Low, then projects horizontal reference lines across the chart. Labels are placed to the right so the key levels are clearly marked.
🔸 10) Row by Row Dominance and Acceptance Reading
Because each row stores total volume, buy volume, sell volume, Value Area membership, and POC status, the indicator gives a layered view of the market:
Where the most activity occurred
Which zones were accepted
Which zones were dominated by buyers
Which zones were dominated by sellers
🔸 11) Premium Visual Presentation
The script uses shaded faces, dedicated POC highlighting, Value Area recoloring, and clean right side labels. This makes it more presentation focused than a basic flat profile and improves chart readability for manual analysis.
🔹 Calculations
1) Profile Range Detection
The script first finds the highest high and lowest low inside the active lookback window. This defines the full vertical range of the volume profile. Only the most recent bars inside that window are used for profile construction.
2) Bin Initialization
Once the recent range is known, the script divides that price range into the chosen number of bins. Each bin stores:
Top boundary
Bottom boundary
Total volume
Buy volume
Sell volume
Flags for Value Area and POC
The bin size is calculated by dividing the total price range by the number of rows.
3) Volume Distribution Across Price Bins
For each candle, the script determines which bins the candle spans. It then spreads that candle’s volume evenly across all touched bins.
This is important because the script does not place the full candle volume into a single price level. Instead, it allocates the candle volume across the portion of the profile that candle covers.
Important implementation note:
This script uses equal distribution across the spanned bins, not proportional overlap weighting. That means each touched row receives the same share of the candle’s volume.
4) Buy Versus Sell Volume Classification
The script classifies each candle as buy dominated or sell dominated using candle direction:
If close is greater than or equal to open, the candle is treated as buy volume
If close is below open, the candle is treated as sell volume
That candle’s allocated volume is then added to either volBuy or volSell inside each touched bin.
This is a practical directional approximation, not true bid ask tape volume.
5) Total Volume and POC Detection
After all candles are processed, the script scans every bin and calculates:
The total volume across the profile
The maximum single bin volume
The POC index
The POC is the bin with the highest total volume. That bin is marked as both isPOC and isVA before Value Area expansion begins.
6) Value Area Expansion Logic
The Value Area is built around the POC by expanding upward and downward until the selected percentage of total profile volume is included.
The script compares the next bin above and the next bin below the current Value Area. It adds whichever side has greater volume first. This continues until cumulative included volume reaches the target Value Area percentage.
This creates a standard profile style Value Area centered on the highest participation region.
7) Histogram Width Normalization
Each row’s width is scaled relative to the maximum volume row:
The row with the most volume becomes the widest
Smaller rows are scaled proportionally
This means width directly communicates relative participation at each price zone.
8) Color Selection Logic
For each bin, the script first determines whether buy volume or sell volume dominates:
If buy volume is greater than or equal to sell volume, it uses the bullish color
Otherwise it uses the bearish color
Then the script overrides that base direction color if needed:
If the row is the POC, it uses the POC color
If the row is inside the Value Area, it uses the Value Area color
This gives the profile a clear visual hierarchy:
POC first
Value Area second
Directional dominance otherwise
9) 3D Face Construction
Each row is rendered as a pseudo 3D object using:
A front rectangle
A shifted back edge using the X and Y depth settings
A side face when horizontal depth is visible
A top or bottom face depending on vertical depth direction
The script shades the side face darker and the top face brighter than the base color to create a depth illusion.
This is a visual projection technique, not a true 3D engine, but it produces a convincing 3D profile effect on the chart.
10) Rendering Order Logic
The script changes draw order depending on the sign of the Y depth:
If vertical depth is positive, rows are drawn from bottom to top
If vertical depth is negative, rows are drawn from top to bottom
This helps the 3D faces stack more cleanly and reduces visual overlap issues.
11) POC, VAH, and VAL Price Calculation
After the profile is complete:
The POC price is the midpoint of the POC bin
VAH is the highest top boundary among all Value Area bins
VAL is the lowest bottom boundary among all Value Area bins
These levels are then drawn as horizontal lines extending from the left side of the lookback window toward the right side label area.
12) Label Placement
The labels for POC, VAH, and VAL are placed slightly to the right of the profile. This keeps them readable and avoids overlap with the 3D bars themselves. 지표

Value Area Levels [crlmx]Calculated from native volume-at-price data vaLevels shows Value Area
levels (VAH, POC, VAL) across three independently configurable timeframes.
Requires TradingView Premium or above plan for Footprint data access,
Short of that refere to Lite version (coming soon).
Key Features
- Three independent VA slots with on/off toggles
- Timeframe selection: D, W, M, 30min, 1H, 4H, 8H, 12H
- Session-based VA on slot 3: NYC, London, Asia, Custom
- Custom session with user-defined time window and label prefix
- Auto-calculated row resolution per instrument type
- Manual ticks-per-row override for fine-tuning
- Configurable Value Area percentage (default 68%)
- Individual VAH, POC, VAL toggles per slot
- Optional price display in labels
- Requires TradingView Premium or Ultimate plan
- Streamlined input / UI brought to you by crlmx
Trading Applications
- Map previous day area against weekly and session VAs to identify confluence zones
- Track VAH/VAL as breakout triggers when price moves outside the prior value area
- Compare session VA (NYC/LDN) against daily VA to for reactions
- When daily and weekly VAs overlap, expect stronger reactions at the shared boundary
- Combine with prLevels for a complete prior-level picture (price levels + volume levels)
- Recommended Settings
Intraday S/R: D + W + NYC | Chart: 1-15 min
Session Trading: D + 4H + LDN | Chart: 1-5 min
Swing Reference: D + W + M | Chart: 30 min - 4H
Version History
- v0.10: Initial release
지표

Price Normalized RSI Profile [UAlgo]Price Normalized RSI Profile is a hybrid visualization tool that combines a rolling RSI distribution study with a profile style overlay drawn directly on the price chart. Instead of plotting a classic RSI line in a separate oscillator pane, this script collects historical RSI readings, groups them into fixed 0 to 100 bins, weights each bin by traded volume, and then renders the resulting distribution as a horizontal profile on the right side of the main chart.
The goal of the script is not to show where price traded the most, but to show where RSI states accumulated the most volume over the selected lookback period. In other words, it answers a different question than a traditional volume profile. Rather than asking which prices were most active, it asks which RSI regimes were most active, then maps those oscillator regimes visually into the chart’s price space for easier on-chart interpretation.
The indicator highlights:
A volume weighted RSI Point of Control (POC)
A Value Area around that POC
A right side histogram of RSI regime distribution
A color gradient that reflects bullish versus bearish RSI zones
Reference labels for POC, VAH, and VAL
Lookback boundary markers for profile context
This makes the script useful for traders who want to blend oscillator distribution analysis with chart based execution, especially when comparing current price position against historically dominant RSI states.
Important note: The POC, VAH, and VAL in this script are derived from an RSI distribution profile , not from a standard price based volume profile. They are visually mapped onto the current chart range for presentation.
🔹 Features
🔸 1) Volume Weighted RSI Distribution Profile
The script collects RSI values over a rolling lookback window and assigns each reading into one of several fixed RSI bins. Each bin accumulates volume , not just frequency, so the profile reflects how much traded participation occurred while RSI was in that zone.
This makes the output more meaningful than a simple occurrence count because highly active bars contribute more weight.
🔸 2) Fixed 0 to 100 RSI Bin Framework
The profile is built over the natural RSI range from 0 to 100, divided into a user defined number of bins. This creates a stable oscillator distribution model that is consistent across symbols and timeframes.
Lower bin counts create thicker, smoother profile bars.
Higher bin counts create finer resolution and more detailed structure.
🔸 3) Overlay on the Main Price Chart
Unlike most RSI tools, this script runs with overlay=true and renders the profile directly on the price chart. It maps RSI bins onto the vertical span of the recent chart range, allowing traders to see the distribution without leaving the main chart.
This is a visual convenience feature and creates a unique fusion of oscillator logic and price space presentation.
🔸 4) Point of Control (POC) Detection
The indicator identifies the RSI bin with the highest accumulated volume and treats it as the RSI Profile POC. This is the most active RSI zone by volume over the lookback window.
The POC is highlighted with:
A wider profile bar
A unique color
A label showing the POC volume
🔸 5) Value Area (VAH / VAL) Calculation
The script builds a Value Area around the POC using the selected percentage of total profile volume. This identifies the core RSI regime zone where the majority of the volume weighted RSI activity occurred.
The Value Area is visually emphasized with more visible bars and separate VAH / VAL guide lines.
🔸 6) Gradient Color Mapping by RSI Regime
Each bin is colored using a gradient based on its RSI location:
Lower RSI zones lean bullish color
Higher RSI zones lean bearish color
This reflects the script’s chosen visual logic, where low RSI bins appear in the bullish color family and high RSI bins appear in the bearish color family.
🔸 7) Distinct Styling for POC, Value Area, and Outside Value
The script visually separates three categories:
POC bin
Bins inside the Value Area
Bins outside the Value Area
This helps traders quickly distinguish the dominant RSI regime from the broader accepted RSI zone and from lower importance outer regions.
🔸 8) Forward Projected Histogram Layout
The profile is drawn to the right of current price using configurable:
Maximum width in bars
Horizontal offset
This keeps the histogram out of the way of current candles while preserving clear visibility on the active chart.
🔸 9) Lookback Context Markers
The script draws a vertical line marking the start of the profile lookback window, plus horizontal guide lines across the chart high and low range used for the profile mapping. This makes it easy to understand which portion of the chart is being analyzed.
🔸 10) Compact On Chart Labels
The indicator adds right side labels for:
POC
VAH
VAL
This makes the distribution easier to read without manually inspecting each bar.
🔸 11) Rolling History Buffer for RSI and Volume
The script stores both RSI and volume into arrays, allowing the profile to be rebuilt from recent history on the last bar. This keeps the logic fully rolling and independent from session boundaries.
🔸 12) Structured Object Based Design
The script uses custom types:
RsiBin for each RSI interval
RsiProfile for the full profile state, including POC and Value Area indexes
This makes the internal logic cleaner and easier to maintain.
🔹 Calculations
1) RSI Calculation
The script calculates RSI from the chosen source and length:
float rsi_val = ta.rsi(rsi_src, rsi_len)
This value is the basis for all binning and profile accumulation.
2) Rolling RSI and Volume History Storage
Every bar, the script pushes the latest RSI value and volume into rolling arrays:
rsi_history.push(rsi_val)
vol_history.push(volume)
To prevent unlimited growth, the arrays are trimmed when they exceed:
lookback + 100
This keeps enough buffer for profile stability while controlling memory size.
3) Fixed RSI Bin Initialization
The profile divides the 0 to 100 RSI range into equal bins:
float step = 100.0 / bins_count
for i = 0 to bins_count - 1
float min_v = i * step
float max_v = (i + 1) * step
this.bins.push(RsiBin.new(min_v, max_v, 0.0, 0))
Each bin stores:
RSI minimum value
RSI maximum value
Accumulated volume
Observation count
4) Volume Weighted Population of the RSI Profile
When populating the profile, each historical RSI value is mapped into the correct bin:
int bin_idx = math.floor(r_val / 100.0 * this.bins.size())
The index is clamped to remain inside valid bounds:
bin_idx := math.min(bin_idx, this.bins.size() - 1)
bin_idx := math.max(bin_idx, 0)
Then the script adds the corresponding bar volume to that bin:
b.volume += v_val
b.count += 1
this.total_vol += v_val
This means the profile is volume weighted RSI distribution , not a simple count histogram.
5) POC Detection
As bins are populated, the script tracks the bin with the highest accumulated volume:
if b.volume > this.max_vol
this.max_vol := b.volume
this.poc_idx := bin_idx
This bin becomes the profile POC and acts as the center for Value Area expansion.
6) Value Area Calculation
The Value Area target is calculated from total profile volume:
float target_vol = this.total_vol * (va_percent / 100.0)
The script starts from the POC and expands outward, comparing the next upper and lower bin volumes:
float vol_up = (top < max_idx) ? this.bins.get(top + 1).volume : 0.0
float vol_dn = (bot > 0) ? this.bins.get(bot - 1).volume : 0.0
Whichever side has more volume is added first. This continues until the accumulated volume reaches the target percentage.
The final indexes are stored as:
this.va_top_idx := top
this.va_bot_idx := bot
7) Mapping RSI Bins into Price Space
A key part of this script is that RSI bins are not drawn in an oscillator pane. Instead, each RSI interval is mapped onto the chart’s recent price range:
float price_range = chart_high - chart_low
float y_bottom = chart_low + (b.min_val / 100.0) * price_range
float y_top = chart_low + (b.max_val / 100.0) * price_range
Interpretation:
RSI 0 maps to the recent chart low.
RSI 100 maps to the recent chart high.
All intermediate RSI bins are proportionally placed between them.
This is a visual mapping device, not a statement that those price levels correspond to actual RSI threshold prices.
8) Histogram Width Normalization
Each bin’s horizontal width is scaled by its volume relative to the maximum profile volume:
int bar_w = math.round((b.volume / this.max_vol) * max_width)
If the bin is the POC, it gets extra width:
if is_poc
bar_w := int(max_width * 1.15)
This makes the POC stand out clearly inside the profile.
9) POC, VA, and Outside VA Styling Logic
Each bin is categorized as:
POC
Inside the Value Area
Outside the Value Area
Then the script applies different opacity and border logic:
POC gets the dedicated POC color
VA bins are more visible
Outside VA bins are more faded
This creates clear visual hierarchy in the profile.
10) Color Gradient by RSI Position
Base color is determined from bin position in the RSI scale:
color base_col = color.from_gradient(b.min_val, 0, 100, c_bull, c_bear)
This means lower RSI bins transition toward the bullish color and higher RSI bins transition toward the bearish color. This is a stylistic mapping choice built into the script.
11) POC Label and Volume Display
When the POC is drawn, the script also adds a label showing:
The text POC
The accumulated volume of that bin
text="POC " + str.tostring(b.volume, format.volume)
This provides quick information about the dominant RSI regime’s participation size.
12) VAH and VAL Price Level Rendering
The script converts the Value Area top and bottom RSI bin indexes into mapped chart levels:
For VAH:
float vah_level = chart_low + (b_vah.max_val / 100.0) * price_range_val
For VAL:
float val_level = chart_low + (b_val.min_val / 100.0) * price_range_val
It then draws dashed horizontal lines and small labels for both.
Important note:
These are RSI profile Value Area boundaries mapped into price space , not true price based VAH and VAL from a market profile.
13) Lookback Boundary Drawing
The start of the lookback window is marked with a vertical dotted line:
int start_bar_idx = bar_index - lookback
line.new(start_bar_idx, chart_low, start_bar_idx, chart_high, ...)
This makes it easier to visually understand which section of chart history contributed to the current profile.
14) Chart Range Anchoring
The vertical display range used for the RSI to price mapping is derived from:
float chart_high = ta.highest(high, lookback)
float chart_low = ta.lowest(low, lookback)
This means the profile always stretches across the full recent visible price range used in the calculation window.
15) Last Bar Rendering Behavior
The profile is built and rendered only on the last bar:
if barstate.islast
vp.init(bin_count)
vp.populate(rsi_history, vol_history, lookback)
vp.calc_va(va_pct)
vp.render(...)
지표

HTF Candle Profile [UAlgo]HTF Candle Profile is a higher timeframe candle visualization tool that rebuilds each selected HTF candle from the lower timeframe bars that form it, then projects a horizontal volume profile inside that HTF candle range. The goal is to make intrabar participation visible directly on the price chart, so you can see where volume concentrated within the candle, where it was thin, and where the dominant traded price level emerged.
Instead of treating a daily or four hour candle as a single block, the script aggregates the lower timeframe bars as they arrive and distributes their volume across price bins covering the HTF candle’s high to low range. The result is a compact profile drawn from the start time of the HTF candle toward the right, with width proportional to relative volume per bin and color intensity driven by a gradient. This provides a fast read of internal structure: balanced candles, directional candles, rejection wicks, and consolidation pockets become easier to interpret because you can see the volume distribution inside the candle.
The indicator draws on the main chart and keeps a small rolling history of recent HTF candles to stay responsive and to respect object limits.
🔹 Features
1) Multi Timeframe HTF Candle Reconstruction
The script listens for a new HTF candle event using the selected timeframe input. When a new HTF candle begins, the previous one is finalized and drawn. During the active HTF candle, each incoming lower timeframe bar updates the running OHLC and stores its high, low, and volume for profiling.
This approach enables a live building profile for the current HTF candle while preserving completed profiles for recent candles.
2) Intrabar Volume Profile Built from LTF Data
For each HTF candle, the price range from low to high is divided into a user defined number of bins. Each lower timeframe bar contributes volume into all bins it spans. Volume is distributed evenly across the spanned bins to approximate participation within that bar’s range. This produces a per bin volume distribution that is stable and visually interpretable even when lower timeframe candles have large ranges.
3) Gradient Based Profile Intensity
Each bin is drawn as a horizontal box. Its color comes from a gradient that maps low volume to a softer profile color and high volume to a stronger profile color. This makes it easy to spot high participation nodes and low participation voids within the HTF candle.
Inputs allow independent control for bullish and bearish candle coloring and for the low volume and high volume profile colors.
4) POC Line Option
The script can optionally plot a POC line representing the price level of maximum volume within the HTF candle. This is drawn as a dashed horizontal line that spans the candle’s start time to end time. POC is often used as a reference for acceptance, fair value, or a magnet level during retracements.
5) Candle Body, Wick, and Time Boundaries
To keep the profile anchored and readable, the script also draws:
A translucent body box from HTF open to HTF close
A vertical wick line from HTF high to HTF low
A dotted start boundary and a dotted end boundary for the HTF candle window
These elements provide context so the profile is always interpreted within the candle structure that produced it.
6) Object Management and Rolling History
To keep charts clean and avoid exceeding platform limits, the script maintains a small history of HTF candles and deletes drawings for older ones. Each candle owns its objects and can fully clear them when removed from the rolling window.
🔹 Calculations
1) New HTF Candle Detection
A new candle event is detected using timeframe change on the selected timeframe:
isNew = timeframe.change(tf)
When isNew is true:
The previous HTF candle is finalized by setting its end time and drawing it
A new HTF candle object is created and added to the array
Old candles beyond the history limit are removed and their drawings deleted
2) HTF Candle Aggregation from LTF Bars
Each incoming lower timeframe bar updates the active HTF candle:
method addLtf(HtfCandle this, float h, float l, float c, float v) =>
this.ltfData.push(LtfBar.new(h, l, v))
this.h := math.max(this.h, h)
this.l := math.min(this.l, l)
this.c := c
Interpretation:
High is updated to the maximum seen so far within the HTF candle window
Low is updated to the minimum seen so far
Close is updated to the most recent close
Each LTF bar is stored with its high, low, and volume for later bin distribution
3) Bin Construction Across the HTF Candle Range
When drawing a candle, the script divides the HTF range into binCount segments:
float step = (this.h - this.l) / bCount
for i = 0 to bCount - 1
this.bins.push(ProfileData.new(this.l + i * step, this.l + (i + 1) * step, 0.0, na))
Each bin stores:
minP and maxP boundaries
accumulated volume for that price segment
a box handle for drawing
4) Volume Distribution from Each LTF Bar into Bins
For each stored LTF bar, the script determines which bins the bar spans and distributes volume evenly across them:
int startIdx = int((ltf.l - this.l) / step)
int endIdx = int((ltf.h - this.l) / step)
startIdx := math.max(0, math.min(startIdx, bCount - 1))
endIdx := math.max(0, math.min(endIdx, bCount - 1))
int spanned = endIdx - startIdx + 1
float vPerBin = ltf.v / spanned
for j = startIdx to endIdx
ProfileData b = this.bins.get(j)
b.vol += vPerBin
Interpretation:
The bar range is mapped to bin indexes
Indexes are clamped so they remain inside the array
Volume is divided by the number of spanned bins
Each spanned bin receives an equal share of that bar’s volume
This is a robust approach for intrabar profiling without tick data.
5) POC Computation
The script finds the bin with the maximum accumulated volume and sets the POC price at the midpoint of that bin:
float maxVol = 0.0
float pocP = na
for b in this.bins
if b.vol > maxVol
maxVol := b.vol
pocP := math.avg(b.minP, b.maxP)
If enabled, a dashed POC line is drawn across the HTF candle window:
if sPoc and not na(pocP)
this.lPoc := line.new(x1=this.st, y1=pocP, x2=this.et, y2=pocP, xloc=xloc.bar_time, color=cPoc, style=line.style_dashed, width=2)
6) Profile Box Width Scaling
Each bin’s box width scales by its volume relative to the maximum volume bin. Width is capped as a fraction of the candle’s time duration:
int duration = math.max(this.et - this.st, 1)
int volWidth = int((duration * 0.40) * (b.vol / maxVol))
int boxRight = this.st + volWidth
Interpretation:
duration represents the HTF candle time width
0.40 is the maximum profile width fraction of the candle duration
b.vol / maxVol converts volume to a normalized ratio
boxRight is calculated so all profile boxes start at the candle start time and extend rightward based on volume
7) Gradient Coloring of the Profile
Each bin color is mapped from low volume to high volume using a gradient:
color gradColor = color.from_gradient(b.vol, 0, maxVol, cLow, cHigh)
This keeps low participation zones visually lighter and high participation zones more prominent.
8) Candle Body and Wick Drawing
The script draws an HTF candle body box and a wick line for context:
float topP = math.max(this.o, this.c)
float botP = math.min(this.o, this.c)
this.bBody := box.new(left=this.st, top=topP, right=this.et, bottom=botP, xloc=xloc.bar_time, bgcolor=color.new(c, 85))
this.lWick := line.new(x1=midTime, y1=this.h, x2=midTime, y2=this.l, xloc=xloc.bar_time, color=color.new(c, 30), width=2)
It also draws start and end boundary lines so the candle window is clearly defined in time.
지표

Volume Profile Skew [BackQuant]Volume Profile Skew
Overview
Volume Profile Skew is a market-structure indicator that answers a specific question most volume profiles do not:
“Is volume concentrating toward lower prices (accumulation) or higher prices (distribution) inside the current profile range?”
A standard volume profile shows where volume traded, but it does not quantify the shape of that distribution in a single number. This script builds a volume profile over a rolling lookback window, extracts the key profile levels (POC, VAH, VAL, and a volume-weighted mean), then computes the skewness of the volume distribution across price bins. That skewness becomes an oscillator, smoothed into a regime signal and paired with visual profile plotting, key level lines, and historical POC tracking.
This gives you two layers at once:
A full profile and its important levels (where volume is).
A skew metric (how volume is leaning within that range).
What this indicator is based on
The foundation comes from classical “volume at price” concepts used in Market Profile and Volume Profile analysis:
POC (Point of Control): the price level with the highest traded volume.
Value Area (VAH/VAL): the zone containing the bulk of activity, commonly 70% of total volume.
Volume-weighted mean (VWMP in this script): the average price weighted by volume, a “center of mass” for traded activity.
Where this indicator extends the idea is by treating the volume profile as a statistical distribution across price. Once you treat “volume by price bin” as a probability distribution (weights sum to 1), you can compute distribution moments:
Mean: where the mass is centered.
Standard deviation: how spread-out it is.
Skewness: whether the distribution has a heavier tail toward higher or lower prices.
This is not a gimmick. Skewness is a standard statistic in probability theory. Here it is applied to “volume concentration across price”, not to returns.
Core concept: what “skew” means in a volume profile
Imagine a profile range from Low to High, split into bins. Each bin has some volume. You can get these shapes:
Balanced profile: volume is fairly symmetric around the mean, skew near 0.
Bottom-heavy profile: more volume at lower prices, with a tail toward higher prices, skew tends to be positive.
Top-heavy profile: more volume at higher prices, with a tail toward lower prices, skew tends to be negative.
In this script:
Positive skew is labeled as ACCUMULATION.
Negative skew is labeled as DISTRIBUTION.
Near-zero skew is NEUTRAL.
Important: accumulation here does not mean “buying will immediately pump price.” It means the profile shape suggests more participation at lower prices inside the current lookback range. Distribution means participation is heavier at higher prices.
How the volume profile is built
1) Define the analysis window
The profile is computed on a rolling window:
Lookback Period: number of bars included (capped by available history).
Profile Resolution (bins): number of price bins used to discretize the high-low range.
The script finds the highest high and lowest low in the lookback window to define the price range:
rangeHigh = highest high in window
rangeLow = lowest low in window
binSize = (rangeHigh - rangeLow) / bins
2) Create bin midpoints
Each bin gets a midpoint “price” used for calculations:
price = rangeLow + binSize * (b + 0.5)
These midpoints are what the mean, variance, and skewness are computed on.
3) Distribute each candle’s volume into bins
This is a key implementation detail. Real volume profiles require tick-level data, but Pine does not provide that. So the script approximates volume-at-price using candle ranges:
For each bar in the lookback:
Determine which bins its low-to-high range touches.
Split that candle’s total volume evenly across the touched bins.
So if a candle spans 6 bins, each bin gets volume/6 from that bar. This is a practical, consistent approximation for “where trading could have occurred” inside the bar.
This approach has tradeoffs:
It does not know where within the candle the volume truly traded.
It assumes uniform distribution across the candle range.
It becomes more meaningful with larger samples (bigger lookback) and/or higher timeframes.
But it is still useful because the purpose here is the shape of the distribution across the whole window, not exact microstructure.
Key profile levels: POC, VAH, VAL, VWMP
POC (Point of Control)
POC is found by scanning bins and selecting the bin with maximum volume. The script stores:
pocIndex: which bin has max volume
poc price: midpoint price of that bin
Value Area (VAH/VAL) using 70% volume
The script builds the value area around the POC outward until it captures 70% of total volume:
Start with the POC bin.
Expand one bin at a time to the side with more volume.
Stop when accumulated volume >= 70% of total profile volume.
Then:
VAL = rangeLow + binSize * lowerIdx
VAH = rangeLow + binSize * (upperIdx + 1)
This produces a classic “where most business happened” zone.
VWMP (Volume-Weighted Mean Price)
This is essentially the center of mass of the profile:
VWMP = sum(price * volume ) / totalVolume
It is similar in spirit to VWAP, but it is computed over the profile bins, not from bar-by-bar typical price.
Skewness calculation: turning the profile into an oscillator
This is the main feature.
1) Treat volumes as weights
For each bin:
weight = volume / totalVolume
Now weights sum to 1.
2) Compute weighted mean
Mean price:
mean = sum(weight * price )
3) Compute weighted variance and std deviation
Variance:
variance = sum(weight * (price - mean)^2)
stdDev = sqrt(variance)
4) Compute weighted third central moment
Third moment:
m3 = sum(weight * (price - mean)^3)
5) Standardize to skewness
Skewness:
rawSkew = m3 / (stdDev^3)
This standardization matters. Without it, the value would explode or shrink based on profile scale. Standardized skewness is dimensionless and comparable.
Smoothing and regime rules
Raw skewness can be jumpy because:
profile bins change as rangeHigh/rangeLow shift,
one high-volume candle can reshape the distribution,
volume regimes change quickly in crypto.
So the indicator applies EMA smoothing:
smoothedSkew = EMA(rawSkew, smooth)
Then it classifies regime using fixed thresholds:
Bullish (ACCUMULATION): smoothedSkew > +0.25
Bearish (DISTRIBUTION): smoothedSkew < -0.25
Neutral: between those values
Signals are generated on threshold cross events:
Bull signal when smoothedSkew crosses above +0.25
Bear signal when smoothedSkew crosses below -0.25
This makes the skew act like a regime oscillator rather than a constantly flipping color.
Volume Profile plotting modes
The script draws the profile on the last bar, using boxes for each bin, anchored to the right with a configurable offset. The width of each profile bar is normalized by max bin volume:
volRatio = binVol / maxVol
barWidth = volRatio * width
Three style modes exist:
1) Gradient
Uses a “jet-like” gradient based on volRatio (blue → red). Higher-volume bins stand out naturally. Transparency increases as volume decreases, so low-volume bins fade.
2) Solid
Uses the current regime color (bull/bear/neutral) for all bins, with transparency. This makes the profile read as “structure + regime.”
3) Skew Highlight
Highlights bins that match the skew bias:
If skew bullish, emphasize lower portion of profile.
If skew bearish, emphasize higher portion of profile.
Else, keep most bins neutral.
This is a visual “where the skew is coming from” mode.
Historical POC tracking and Naked POCs
This script also treats POCs as meaningful levels over time, similar to how traders track old VA levels.
What is a “naked POC”?
A “naked POC” is a previously formed POC that has not been revisited (retested) by price since it was recorded. Many traders watch these as potential reaction zones because they represent prior “maximum traded interest” that the market has not re-engaged with.
How this script records POCs
It stores a new historical POC when:
At least updatebars have passed since the last stored POC, and
The POC has changed by at least pochangethres (%) from the last stored value.
New stored POCs are flagged as naked by default.
How naked becomes tested
On each update, the script checks whether price has entered a small zone around a naked POC:
zoneSize = POC * 0.002 (about 0.2%)
If bar range overlaps that zone, mark it as tested (not naked).
Display controls:
Highlight Naked POCs: draws and labels untested POCs.
Show Tested POCs: optionally draw tested ones in a muted color.
To avoid clutter, the script limits stored POCs to the most recent 20 and avoids drawing ones too close to the current POC.
On-chart key levels and what they mean
When enabled, the script draws the current lookback profile levels on the price chart:
POC (solid): the “most traded” price.
VAH/VAL (dashed): boundaries of the 70% value area.
VWMP (dotted): volume-weighted mean of the profile distribution.
Interpretation framework (practical, not mystical):
POC often behaves like a magnet in balanced conditions.
VAH/VAL define the “accepted” area, breaks can signal auction continuation.
VWMP is a fair-value reference, useful as a mean anchor when skew is neutralizing.
Oscillator panel and histogram
The skew oscillator is plotted in a separate pane:
Line: smoothedSkew, colored by regime.
Histogram: smoothedSkew as bars, colored by sign.
Fill: subtle shading above/below 0 to reinforce bias.
This makes it easy to read:
Direction of bias (positive vs negative).
Strength (distance from 0 and from thresholds).
Transitions (crosses of ±0.25).
Info table: what it summarizes
On the last bar, a table prints key diagnostics:
Current skew value (smoothed).
Regime label (ACCUMULATION / DISTRIBUTION / NEUTRAL).
Current POC, VAH, VAL, VWMP.
Count of naked POCs still active.
A simple “volume location” hint (lower/higher/balanced).
This is designed for quick scanning without reading the entire profile.
Alerts
The indicator includes alerts for:
Skew regime shifts (cross above +0.25, cross below -0.25).
Price crossing above/below current POC.
Approaching a naked POC (within 1% of any active naked POC).
The “approaching naked POC” alert is useful as a heads-up that price is entering a historically important volume magnet/reaction zone.
How to use it properly
1) Regime filter
Use skew regime to decide what type of trades you should prioritize:
ACCUMULATION (positive skew): market activity is heavier at lower prices, pullbacks into value or below VWMP often matter more.
DISTRIBUTION (negative skew): activity is heavier at higher prices, rallies into value or above VWMP often matter more.
NEUTRAL: mean-reversion and POC magnet behavior tends to dominate.
This is not “buy when green.” It is context for what the auction is doing.
2) Level-based execution
Combine skew with VA/POC levels:
In neutral regimes, expect rotations around POC and inside VA.
In strong skew regimes, watch for acceptance away from POC and reactions at VA edges.
3) Naked POCs as targets and reaction zones
Naked POCs can act like unfinished business. Common workflows:
As targets in rotations.
As areas to reduce risk when price is approaching.
As “if it breaks cleanly, trend continuation” markers when price returns with force.
Parameter tuning guidance
Lookback
Controls how “local” the profile is.
Shorter: reacts faster, more sensitive to recent moves.
Longer: more stable, better for swing context.
Bins
Controls resolution of the profile.
Higher bins: more detail, more computation, more sensitive profile shape.
Lower bins: smoother, less detail, more stable skew.
Smoothing
Controls how noisy the skew oscillator is.
Higher smoothing: fewer regime flips, slower response.
Lower smoothing: more responsive, more false transitions.
POC tracking settings
Update interval and threshold decide how many historical POCs you store and how different they must be. If you set them too loose, you will spam levels. If too strict, you will miss meaningful shifts.
Limitations and what not to assume
This indicator uses candle-range volume distribution because Pine cannot see tick-level volume-at-price. That means:
The profile is an approximation of where volume could have traded, not exact tape data.
Skew is best treated as a structural bias, not a precise signal generator.
Extreme single-bar events can distort the distribution briefly, smoothing helps but cannot remove reality.
Summary
Volume Profile Skew takes standard volume profile structure (POC, Value Area, volume-weighted mean) and adds a statistically grounded measure of profile shape using skewness. The result is a regime oscillator that quantifies whether volume concentration is leaning toward lower prices (accumulation) or higher prices (distribution), while also plotting the full profile, key levels, and historical naked POCs for actionable context.
지표

지표

RSI Profile [Kodexius]RSI Profile is an advanced technical indicator that turns the classic RSI into a distribution profile instead of a single oscillating line. Rather than only showing where the RSI is at the current bar, it displays where the RSI has spent most of its time or most of its volume over a user defined lookback period.
The script builds a histogram of RSI values between 0 and 100, splits that range into configurable bins, and then projects the result to the right side of the chart. This gives you a clear visual representation of the RSI structure, including the Point of Control (POC), the Value Area High (VAH), and the Value Area Low (VAL). The POC marks the RSI level with the highest activity, while VAH and VAL bracket the percentage based value area around it.
By combining standard RSI, a distribution profile, and value area logic, this tool lets you study RSI behavior statistically instead of only bar by bar. You can immediately see whether the current RSI reading is located inside the dominant zone, extended above it, or depressed below it, and whether the recent regime has been biased toward overbought, oversold, or neutral territory. This is particularly useful for swing traders, mean reversion systems, and anyone who wants to integrate RSI context into a more profile oriented workflow.
🔹 Features
1. RSI-Based Distribution Profile
-Builds a histogram of RSI values between 0 and 100.
-The RSI range is divided into a user-defined number of bins (e.g., 30 bins).
-Each bin represents a band of RSI values, such as 0–3.33, 3.33–6.66, ..., 96.66–100.
-For each bar in the lookback period, the script:
-Finds which bin the RSI value belongs to
Adds either:
-1.0 → if using time/frequency
-volume → if using volume-weighted RSI distribution
This creates a clear profile of where RSI has been concentrated over the chosen lookback window.
2. Time / Volume Weighting Mode
Under Profile Settings, you can choose:
-Weight by Volume = false
→ Profile is built using time spent at each RSI level (frequency).
-Weight by Volume = true
→ Profile is built using volume traded at each RSI level.
This flexibility allows you to decide whether you want:
-A pure momentum structure (time spent at each RSI)
-Or a participation-weighted structure (where higher-volume zones are emphasized)
3. Configurable Lookback & Resolution
-Profile Lookback: number of historical bars to analyze.
-Number of Bins: controls the resolution of the histogram:
Fewer bins → smoother, fewer gaps
More bins → more detail, but potentially more visual sparsity
-Profile Width (Bars): defines how wide the histogram extends into the future (visually), converted into time using average bar duration.
This provides a balance between performance, clarity, and visual density.
4. Value Area, POC, VAH, VAL
The script computes:
-POC (Point of Control)
→ The RSI bin with the highest total value (time or volume).
-Value Area (VA)
→ The range of RSI bins that contain a user-specified percentage of total activity (e.g., 70%).
-VAH & VAL
→ Upper and lower RSI boundaries of this Value Area.
These are then drawn as horizontal lines and labeled:
-POC line and label
-VAH line and label
-VAL line and label
This gives you a profile-style view similar to classical volume profile, but entirely on the RSI axis.
5. Color Coding & Visual Design
The histogram bars (boxes) are colored using a smart scheme:
-Below 30 RSI → Oversold zone, uses the Oversold Color (default: green).
-Above 70 RSI → Overbought zone, uses the Overbought Color (default: red).
-Between 30 and 70 RSI → Neutral zone, uses a gradient between:
A soft blue at lower mid levels
A soft orange at higher mid levels
Additional styling:
-POC bin is highlighted in bright yellow.
-Bins inside the Value Area → lower transparency (more solid).
-Bins outside the Value Area → higher transparency (faded).
This makes it easy to visually distinguish:
-Core RSI activity (VA)
-Extremes (oversold/overbought)
-The single dominant zone (POC)
🔹 Calculations
This section summarizes the core logic behind the script and highlights the main building blocks that power the profile.
1. Profile Structure and Bin Initialization
A custom Profile type groups together configuration, bins and drawing objects. During initialization, the script splits the 0 to 100 RSI range into evenly spaced bins, each represented by a Bin record:
method initBins(Profile p) =>
p.bins := array.new()
float step = 100.0 / p.binCount
for i = 0 to p.binCount - 1
float low = i * step
float high = (i + 1) * step
p.bins.push(Bin.new(low, high, 0.0, box(na)))
2. Filling the Profile Over the Lookback Window
On the last bar, the script clears previous drawings and walks backward through the selected lookback window. For each historical bar, it reads the RSI and volume series and feeds them into the profile:
if barstate.islast
myProfile.reset()
int start = math.max(0, bar_index - lookback)
int end = bar_index
for i = 0 to (end - start)
float r = rsi
float v = volume
if not na(r)
myProfile.add(r, v)
The add method converts each RSI value into a bin index and accumulates either a frequency count or the bar volume, depending on the chosen mode:
method add(Profile p, float rsiValue, float volumeValue) =>
int idx = int(rsiValue / (100.0 / p.binCount))
if idx >= p.binCount
idx := p.binCount - 1
if idx < 0
idx := 0
Bin targetBin = p.bins.get(idx)
float addedValue = p.useVolume ? volumeValue : 1.0
targetBin.value += addedValue
3. Finding POC and Building the Value Area
Inside the draw method, the script first scans all bins to determine the maximum value and the total sum. The bin with the highest value becomes the POC. The value area is then constructed by expanding from that center bin until the desired percentage of total activity is covered:
for in p.bins
totalVal += b.value
if b.value > maxVal
maxVal := b.value
pocIdx := i
float vaTarget = totalVal * (p.vaPercent / 100.0)
float currentVaVol = maxVal
int upIdx = pocIdx
int downIdx = pocIdx
while currentVaVol < vaTarget
float upVol = (upIdx < p.binCount - 1) ? p.bins.get(upIdx + 1).value : 0.0
float downVol = (downIdx > 0) ? p.bins.get(downIdx - 1).value : 0.0
if upVol == 0 and downVol == 0
break
if upVol >= downVol
upIdx += 1
currentVaVol += upVol
else
downIdx -= 1
currentVaVol += downVol
지표

MFI Volume Profile [Kodexius]The MFI Volume Profile indicator blends a classic volume profile with the Money Flow Index so you can see not only where volume traded, but also how strong the buying or selling pressure was at those prices. Instead of showing a simple horizontal histogram of volume, this tool adds a money flow dimension and turns the profile into a price volume momentum heat map.
The script scans a user controlled lookback window and builds a set of price levels between the lowest and highest price in that period. For every bar inside that window, its volume is distributed across the price levels that the bar actually touched, and that volume is combined with the bar’s MFI value. This creates a volume weighted average MFI for each price level, so every row of the profile knows both how much volume traded there and what the typical money flow condition was when that volume appeared.
On the chart, the indicator plots a stack of horizontal boxes to the right of current price. The length of each box represents the relative amount of volume at that price, while the color represents the average MFI there. Levels with stronger positive money flow will lean toward warmer shades, and levels with weaker or negative money flow will lean toward cooler or more neutral shades inside the configured MFI band. Each row is also labeled in the format Volume , so you can instantly read the exact volume and money flow value at that level instead of guessing.
This gives you a detailed map of where the market really cared about price, and whether that interest came with strong inflow or outflow. It can help you spot areas of accumulation, distribution, absorption, or exhaustion, and it does so in a compact visual that sits next to price without cluttering the candles themselves.
Features
Combined volume profile and MFI weighting
The indicator builds a volume profile over a user selected lookback and enriches each price row with a volume weighted average MFI. This lets you study both participation and money flow at the same price level.
Volume distributed across the bar price range
For every bar in the window, volume is not assigned to a single price. Instead, it is proportionally distributed across all price rows between the bar low and bar high. This creates a smoother and more realistic profile of where trading actually happened.
MFI based color gradient between 30 and 70
Each price row is colored according to its average MFI. The gradient is anchored between MFI values of 30 and 70, which covers typical oversold, neutral and overbought zones. This makes strong demand or distribution areas easier to spot visually.
Configurable structure resolution and depth
Main user inputs are the lookback length, the number of rows, the width of the profile in bars, and the label text size. You can quickly switch between coarse profiles for a big picture and higher resolution profiles for detailed structure.
Numeric labels with volume and MFI per row
Every box is labeled with the total volume at that level and the average MFI for that level, in the format Volume . This gives you exact values while still keeping the visual profile clean and compact.
Calculations
Money Flow Index calculation
currentMfi is calculated once using ta.mfi(hlc3, mfiLen) as usual,
Creation of the profileBins array
The script creates an array named profileBins that will hold one VPBin element per price row.
Each VPBin contains
volume which is the total volume accumulated at that price row
mfiProduct which is the sum of volume multiplied by MFI for that row
The loop;
for i = 0 to rowCount - 1 by 1
array.push(profileBins, VPBin.new(0.0, 0.0))
pre allocates a clean structure with zero values for all rows.
Finding highest and lowest price across the lookback
The script starts from the current bar high and low, then walks backward through the lookback window
for i = 0 to lookback - 1 by 1
highestPrice := math.max(highestPrice, high )
lowestPrice := math.min(lowestPrice, low )
After this loop, highestPrice and lowestPrice define the full price range covered by the chosen lookback.
Price range and step size for rows
The code computes
float rangePrice = highestPrice - lowestPrice
rangePrice := rangePrice == 0 ? syminfo.mintick : rangePrice
float step = rangePrice / rowCount
rangePrice is the total height of the profile in price terms. If the range is zero, the script replaces it with the minimum tick size for the symbol. Then step is the price height of each row. This step size is used to map any price into a row index.
Processing each bar in the lookback
For every bar index i inside the lookback, the script checks that currentMfi is not missing. If it is valid, it reads the bar high, low, volume and MFI
float barTop = high
float barBottom = low
float barVol = volume
float barMfi = currentMfi
Mapping bar prices to bin indices
The bar high and low are converted into row indices using the known lowestPrice and step
int indexTop = math.floor((barTop - lowestPrice) / step)
int indexBottom = math.floor((barBottom - lowestPrice) / step)
Then the indices are clamped into valid bounds so they stay between zero and rowCount - 1. This ensures that every bar contributes only inside the profile range
Splitting bar volume across all covered bins
Once the top and bottom indices are known, the script calculates how many rows the bar spans
int coveredBins = indexTop - indexBottom + 1
float volPerBin = barVol / coveredBins
float mfiPerBin = volPerBin * barMfi
Here the total bar volume is divided equally across all rows that the bar touches. For each of those rows, the same fraction of volume and volume times MFI is used.
Accumulating into each VPBin
Finally, a nested loop iterates from indexBottom to indexTop and updates the corresponding VPBin
for k = indexBottom to indexTop by 1
VPBin binData = array.get(profileBins, k)
binData.volume := binData.volume + volPerBin
binData.mfiProduct := binData.mfiProduct + mfiPerBin
Over all bars in the lookback window, each row builds up
total volume at that price range
total volume times MFI at that price range
Later, during the drawing stage, the script computes
avgMfi = bin.mfiProduct / bin.volume
for each row. This is the volume weighted average MFI used both for coloring the box and for the numeric MFI value shown in the label Volume . 지표

Volume Profile Area [BigBeluga]🔵 OVERVIEW
The Volume Profile Area is an advanced profiling tool that calculates and visualizes the value area within a chosen period’s volume distribution. It first builds a main profile of the entire range, then constructs a secondary profile inside the defined value area, allowing traders to examine market balance and key trading zones in greater detail.
🔵 CONCEPTS
Volume Profile – Distributes traded volume across price levels to highlight areas of market activity.
Value Area (VA) – The price range containing a chosen percentage of total volume (commonly 50–70%).
Point of Control (PoC) – The price level with the highest traded volume, often acting as a magnet for price.
Nested Profiles – A profile inside the VA adds a second layer of precision, showing where liquidity clusters within the “fair value” zone.
🔵 FEATURES
Main Profile – Full distribution of volume over the selected lookback period.
Secondary Profile – Built only inside the VA of the main profile, highlighting intrabalance structure.
Customizable PoC Selection – Choose between showing the PoC of the
Main Profile ,
the Area Profile ,
their Average ,
or None .
Dynamic Value Area Levels – Automatically plots VAL (Value Area Low) and VAH (Value Area High) with labels.
Overlay Toggles – Show/hide range extremes, VA lines, or PoCs for a cleaner chart view.
Visual Profiles – Main profile shaded in darker blue; the VA profile inside is lighter for clear separation.
Automatic Scaling – Profiles adapt to period highs/lows and auto-adjust bins for consistent resolution.
Volume Labels – PoCs can display traded volume, giving numeric confirmation of liquidity concentration.
🔵 HOW TO USE
Set the Period to define how many bars to include in the main profile.
Adjust the Value Area % to control how much volume defines the VA (e.g., 50% by default).
Pick your PoC option: Main , Area , or Average , depending on focus.
Use VAH/VAL lines as support/resistance levels where most trading occurred.
Compare reactions at Main vs VA PoC levels to spot potential breakouts or mean reversions.
🔵 CONCLUSION
The Volume Profile Area extends traditional profiling by nesting a secondary VA profile inside the main distribution. This dual-layer approach reveals not just where the market was active overall, but where liquidity concentrated within the “fair value” zone—powerful for refining entries, exits, and risk placement across intraday and swing horizons. 지표

지표

Market sessions and Volume profile - By LeviathanThis script allows you to keep track of Forex market sessions (Tokyo, London and New York), as well as Daily, Weekly and Monthly sessions. All of them are accompanied by Volume Profile options where you can view VP Histogram, Point of Control, Value Area High and Value Area Low.
Colors, lines and other design preferences are fully customizable.
* Volume Profile of shorter sessions (eg. Tokyo, London, New York) works better when using lower timeframes such as 15min, 5min, etc.
** Use timeframe higher than 15min when viewing Monthly sessions
Indicator settings overview:
SESSION TYPE
- Tokyo session (1:00 - 9:00 UTC/ GMT )
- London session (7:00 - 16:00 UTC/ GMT )
- New York session (13:00 - 22:00 UTC/ GMT )
- Daily session
- Weekly session
- Monthly session
DISPLAY
- Show Volume Profile (Show or hide Volume Profile histogram)
- Show POC (Show or hide Point Of Control line)
- Show VAL (Show or hide Value Area Low line)
- Show VAH (Show or hide Value Area High line)
- Show Live Zone (Show or hide the ongoing session)
VOLUME PROFILE SETTINGS
- Resolution (The higher the value, the more refined of a profile, but less profiles are shown on the chart)
- Smooth Volume Data (Useful for assets that have very large spikes in volume over large bars, helps create better profiles)
APPEARANCE
- Up Volume color (Pick a custom color for up/ bullish volume profile nodes)
- Down Volume color (Pick a custom color for down/ bearish volume profile nodes)
- POC color and thickness (Pick a custom color and thickness for Point Of Control line)
- VAH color and thickness (Pick a custom color and thickness for Value Area High line)
- VAL color and thickness (Pick a custom color and thickness for Value Area Low line)
- Session box thickness (Pick a custom thickness for the session box. Color is provided automatically with optimal contrast)
** Some VP elements are inspired by @LonesomeTheBlue's volume profile script 지표

Volume/Market ProfileVolume/Market Profile is a 2 in 1 Volume Profile and Market Profile Indicator.
This indicator is my own calculations for compiling a volume profile and market profile.
The profile is progressively calculated live as the chart develops.
I have made use of both Boxes AND Lines to allow me to display a finer granularity profile by displaying up to twice the max amount of lines allowed in tradingview.
I have spent a lot of time to make sure the values are getting appended exactly as intended so that I can assure this profile is operating as precisely as possible within the limitations of the data available.
To make my calculations easier to use in other places, I have made my volume profile a function that can be extracted and used whenever you need values from a volume profile.
Feel free to read through the script if you don't understand how this profile is developed. I have made a commentary of my volume profile function to help you understand what exactly happens to compile the profiles.
As mentioned before, This indicator doubles as a market profile. To view both at the same time you will need to add the indicator on your chart twice.
I have built in comprehensive customizations to allow you to display your profiles however fits your needs.
Timeframe: The aggregation period for profiles, to see a 1 week profile, change the timeframe to 1 week.
Note: You can add custom timeframes by adding a custom timeframe in your chart timeframe dropdown menu. When you add timeframes in this area, they appear as options within indicators with the timeframe input.
Sensitivity: Allows for greater or less granularity changes. The calculation method for granularity automatically changes depending on the range of your chart.
Note: Multiply this value by 100 and that will be the max range (in ticks) of your price before the indicator automatically adjusts to make the profile less granular. (ex. If price ranges $1, and 1 tick is $0.01, granularity will be 0.01 with a sensitivity of 1+)
Value Area %: % of total volume to display as the value zone. (_% of total profile values are contained within the value zone)
Calculate as Market Profile: Uses a 1 Instead of the candle volume, to display a Market Profile. (If selected POC -> TPOC)
Display Size: Sets the # of bars from the profile axis to the profile's max value. If set negative, profile will be displayed left of axis, if positive, profile will be displayed to the right of the axis.
Display Offset: Sets the # of bars in front(or behind) the current chart bar to set the axis of the profile. If negative, the axis will be to the left of the current chart bar, if positive the axis will be right of the current chart bar.
Display Historical POC/VAH/VAL: Choose to display historical poc,vah,val lines.
Colors: I'm not explaining colors.
Enjoy! 지표

지표

Volume Profile [Makit0]VOLUME PROFILE INDICATOR v0.5 beta
Volume Profile is suitable for day and swing trading on stock and futures markets, is a volume based indicator that gives you 6 key values for each session: POC, VAH, VAL, profile HIGH, LOW and MID levels. This project was born on the idea of plotting the RTH sessions Value Areas for /ES in an automated way, but you can select between 3 different sessions: RTH, GLOBEX and FULL sessions.
Some basic concepts:
- Volume Profile calculates the total volume for the session at each price level and give us market generated information about what price and range of prices are the most traded (where the value is)
- Value Area (VA): range of prices where 70% of the session volume is traded
- Value Area High (VAH): highest price within VA
- Value Area Low (VAL): lowest price within VA
- Point of Control (POC): the most traded price of the session (with the most volume)
- Session HIGH, LOW and MID levels are also important
There are a huge amount of things to know of Market Profile and Auction Theory like types of days, types of openings, relationships between value areas and openings... for those interested Jim Dalton's work is the way to come
I'm in my 2nd trading year and my goal for this year is learning to daytrade the futures markets thru the lens of Market Profile
For info on Volume Profile: TV Volume Profile wiki page at www.tradingview.com
For info on Market Profile and Market Auction Theory: Jim Dalton's book Mind over markets (this is a MUST)
BE AWARE: this indicator is based on the current chart's time interval and it only plots on 1, 2, 3, 5, 10, 15 and 30 minutes charts.
This is the correlation table TV uses in the Volume Profile Session Volume indicator (from the wiki above)
Chart Indicator
1 - 5 1
6 - 15 5
16 - 30 10
31 - 60 15
61 - 120 30
121 - 1D 60
This indicator doesn't follow that correlation, it doesn't get the volume data from a lower timeframe, it gets the data from the current chart resolution.
FEATURES
- 6 key values for each session: POC (solid yellow), VAH (solid red), VAL (solid green), profile HIGH (dashed silver), LOW (dashed silver) and MID (dotted silver) levels
- 3 sessions to choose for: RTH, GLOBEX and FULL
- select the numbers of sessions to plot by adding 12 hours periods back in time
- show/hide POC
- show/hide VAH & VAL
- show/hide session HIGH, LOW & MID levels
- highlight the periods of time out of the session (silver)
- extend the plotted lines all the way to the right, be careful this can turn the chart unreadable if there are a lot of sessions and lines plotted
SETTINGS
- Session: select between RTH (8:30 to 15:15 CT), GLOBEX (17:00 to 8:30 CT) and FULL (17:00 to 15:15 CT) sessions. RTH by default
- Last 12 hour periods to show: select the deph of the study by adding periods, for example, 60 periods are 30 natural days and around 22 trading days. 1 period by default
- Show POC (Point of Control): show/hide POC line. true by default
- Show VA (Value Area High & Low): show/hide VAH & VAL lines. true by default
- Show Range (Session High, Low & Mid): show/hide session HIGH, LOW & MID lines. true by default
- Highlight out of session: show/hide a silver shadow over the non session periods. true by default
- Extension: Extend all the plotted lines to the right. false by default
HOW TO SETUP
BE AWARE THIS INDICATOR PLOTS ONLY IN THE FOLLOWING CHART RESOLUTIONS: 1, 2, 3, 5, 10, 15 AND 30 MINUTES CHARTS. YOU MUST SELECT ONE OF THIS RESOLUTIONS TO THE INDICATOR BE ABLE TO PLOT
- By default this indicator plots all the levels for the last RTH session within the last 12 hours, if there is no plot try to adjust the 12 hours periods until the seesion and the periods match
- For Globex/Full sessions just select what you want from the dropdown menu and adjust the periods to plot the values
- Show or hide the levels you want with the 3 groups: POC line, VA lines and Session Range lines
- The highlight and extension options are for a better visibility of the levels as POC or VAH/VAL
THANKS TO
@watsonexchange for all the help, ideas and insights on this and the last two indicators (Market Delta & Market Internals) I'm working on my way to a 'clean chart' but for me it's not an easy path
@PineCoders for all the amazing stuff they do and all the help and tools they provide, in special the Script-Stopwatch at that was key in lowering this indicator's execution time
All the TV and Pine community, open source and shared knowledge are indeed the best way to help each other
IF YOU REALLY LIKE THIS WORK, please send me a comment or a private message and TELL ME WHAT you trade, HOW you trade it and your FAVOURITE SETUP for pulling out money from the market in a consistent basis, I'm learning to trade (this is my 2nd year) and I need all the help I can get
GOOD LUCK AND HAPPY TRADING 지표
