Value Area and Point of Control
Value Area and Point of Control (POC) are volume-profile metrics that identify the range and single price level where the most trading activity concentrated during a session. Value Area typically encompasses 70% of that session's volume; the POC is the single price with the highest volume. Together, they show where the market spent most of its time and effort, helping traders identify support, resistance, and fair value without relying on time-based bars alone. These tools are useful for scalpers, swing traders, and market-structure analysts who want to understand where volume clustered within a session.
//@version=6
indicator("Value Area & POC [Session Volume]", overlay=true)
// ===== INPUTS =====
vaPercentile = input.float(70.0, title="Value Area %", minval=50, maxval=95, step=5) / 100.0
pocColor = input.color(color.new(color.orange, 0), title="POC Color")
vaColor = input.color(color.new(color.blue, 20), title="VA Color")
sessionInput = input.string("regular", title="Session", options=["regular", "extended", "us_market"])
priceStepInput = input.int(10, title="Price Step (pips/ticks)", minval=1)
// ===== SESSION MAPPING =====
sessionMap = switch sessionInput
"extended" => "EXTM"
"us_market" => "REGULAR"
=> "REGULAR"
// ===== LOGIC =====
var float pocPrice = na
var float vaHigh = na
var float vaLow = na
var bool sessionChanged = false
var array<float> prices = array.new<float>()
var array<float> vols = array.new<float>()
// Check if new session
isNewSession = ta.change(time(sessionMap)) != 0 or barstate.isfirst
if isNewSession and not barstate.isfirst
// Process prior session
if array.size(prices) > 0
// Find POC (max volume price)
maxVol = array.max(vols)
pocIdx = array.indexof(vols, maxVol)
pocPrice := array.get(prices, pocIdx)
// Find Value Area (cumulative 70%)
totalVol = array.sum(vols)
targetVol = totalVol * vaPercentile
cumVol = 0.0
loIdx = 0
hiIdx = array.size(vols) - 1
for i = pocIdx to array.size(vols) - 1 by 1
cumVol += array.get(vols, i)
if cumVol >= targetVol
hiIdx := i
break
cumVol := 0.0
for i = pocIdx to 0 by -1
cumVol += array.get(vols, i)
if cumVol >= targetVol
loIdx := i
break
vaHigh := array.get(prices, hiIdx)
vaLow := array.get(prices, loIdx)
// Reset for new session
array.clear(prices)
array.clear(vols)
// Build price/volume map for current bar
if not isNewSession or barstate.isfirst
price_step = close - (close % (syminfo.pointvalue * priceStepInput))
if array.size(prices) == 0 or array.get(prices, array.size(prices) - 1) != price_step
array.push(prices, price_step)
array.push(vols, volume)
else
idx = array.size(vols) - 1
array.set(vols, idx, array.get(vols, idx) + volume)
// ===== PLOTTING =====
// Value Area
plot(vaHigh, title="VA High", color=vaColor, linewidth=2, style=plot.style_linebr)
plot(vaLow, title="VA Low", color=vaColor, linewidth=2, style=plot.style_linebr)
fill(plot(vaHigh), plot(vaLow), title="VA Fill", color=color.new(vaColor, 85))
// Point of Control
plot(pocPrice, title="POC", color=pocColor, linewidth=3, style=plot.style_linebr)
How the code works
The indicator builds a volume profile for each session by stepping through bars and bucketing volume into price levels. On each bar, the close price is rounded to the specified step size (tick or pip count); volume is accumulated at that price level. When a new session begins, detected by a change in the session time, the prior session's volume profile is analyzed.
The Point of Control is found by locating the price level with the maximum volume (array.max(vols)). The Value Area is computed by starting from the POC and expanding upward and downward simultaneously, accumulating volume outward until the cumulative total reaches the target percentage (default 70%) of the session's total volume. The high and low bounds of that range are plotted continuously across bars.
Key inputs include the VA percentile (how much of the session's volume to enclose), price step granularity (to control bucketing), and session type (regular, extended, or US market hours). Colors for POC and VA can be customized.
Reading it on a chart
The POC line marks the single price level where the most volume traded. Expect price to gravitate toward or rest on this level during the session; it often acts as a magnet and may serve as intraday support or resistance.
The Value Area band (shaded between VA High and VA Low) shows the fair-value range where 70% of the session's volume occurred. Prices outside this band at the session's end signal exhaustion or a directional move that failed to retrace. Price re-entering the VA often signals a retest of fair value. Traders use wide VA as a sign of uncertainty and narrow VA as consensus around a price level.
When POC is near the session's open, the market established a price quickly and held it. When POC is far from the open, buying and selling were distributed across a wider range. Note that gaps from the prior session's close may distort intraday interpretation.
Limitations
-
Session definition is imprecise. The indicator uses only bars within the selected session window; actual market microstructure (opening gaps, pre-market spikes) may not align perfectly with Pine's session boundaries, especially in forex or crypto markets that trade 24/5.
-
Price bucketing is arbitrary. The step size (in pips or ticks) controls granularity; too coarse and you lose detail, too fine and you create noise. No universal "correct" step size exists; it requires manual tuning per instrument.
-
Cumulative volume assumption. The code assumes each bar's volume belongs entirely to the bar's close price after rounding to the step. Intrabar volume distribution is unknown, so the profile is a crude estimate.
-
Repainting within session. The VA and POC persist across bars within a session and are recalculated only at session boundary. Within the session, the plots extend backward, creating a visual illusion of "history" that was only locked in after the session closed.
-
Lookback lag. POC and VA are only finalized at the next session's open. Traders viewing intraday do not know the final profile until the session is over, limiting live decision-making.
-
Volume weighting blind spot. The code weights all volume equally per price bucket; it ignores whether volume came from aggressive buyers, liquidation, or passive fills, each of which may carry different significance.
-
Extended/overnight sessions. In equity markets, regular session POC/VA may differ sharply from overnight sessions; the indicator does not separately analyze or flag this variance.
Key definitions
Value Area: A price range, typically containing 70% of a session's volume, used to identify the range where the market spent most of its time and effort.
Point of Control (POC): The single price level with the highest volume traded during a session.
Session: A defined time period (e.g., US regular market hours, extended hours) during which volume is measured; sessions reset at defined boundaries.
Volume profile: A distribution of volume across price levels, showing where trading concentrated.
Fair value: The price level or range where buyers and sellers agreed most actively during a session, often indicated by high volume.
References
- CME Group, "Market Profile," Education, https://www.cmegroup.com/education
- J. F. Carter, "Mastering the Trade: Proven Techniques for Profiting from Intraday and Swing Trading Setups," John Wiley & Sons (2013).
- James L. Dalton, Robert B. Dalton, and Eric T. Jones, "Markets in Profile: Profiting from the Auction Process," John Wiley & Sons (2007).
- TradingView, "Pine Script Reference Manual," https://www.tradingview.com/pine-script-docs/
- CME Group, "Volume Analysis and Trading," https://www.cmegroup.com/education/courses/volume-analysis
Educational research on historical data only. Not investment advice, not a signal, and never a performance promise. Past results do not predict future performance. Every reference is link-verified before publication and every paper is re-audited weekly against the library's editorial standard.
Last reviewed by the PropLedger research pipeline: 2026-09-27. Educational research on historical data, not financial advice.
Keep reading
Futures Contract Roll and Expiry Week Shading
Free open-source Pine Script indicator: contract roll and expiry week shading for futures. Full code and a plain-English walkthrough.
Turn-of-Month Countdown
Free open-source Pine Script indicator: turn-of-month countdown and shading. Full code and a plain-English walkthrough.
Time-of-Day Volatility Curve
Free open-source Pine Script indicator: time-of-day average volatility curve. Full code and a plain-English walkthrough.