Pine Script Volume: Data Checks and a Spike Indicator
Pine Script exposes bar-level activity through volume, but its meaning depends on the symbol and feed. It can represent traded shares, contracts, other units, or tick activity, and some symbols do not supply it. A useful volume indicator checks availability before interpreting a large number as a signal.
Establish what the data represents
Use the exchange-qualified symbol and inspect TradingView's data information. Do not assume a forex tick count is comparable with stock share volume or that every crypto feed uses the same unit. TradingView's chart-information documentation describes the built-in market data available to scripts.
A bar's total does not count unique participants, reveal institutional identity, or express conviction directly. Each completed trade has both a buyer and a seller. Coloring volume by the candle's direction is a visual classification, not a reconstruction of aggressor-side transactions.
A complete volume-spike example
This v6 indicator compares the current bar with the average volume of the preceding bars. The current bar is excluded from the reference average. It requires a positive baseline and keeps unavailable data distinct from zero.
//@version=6
indicator("Volume Relative to Prior Bars", overlay=false)
length = input.int(20, "Baseline length", minval=1)
multiple = input.float(1.5, "Spike multiple", minval=0.1, step=0.1)
baseline = ta.sma(volume, length)[1]
valid = not na(volume) and not na(baseline) and baseline > 0
spike = valid and volume > baseline * multiple
barColor = spike ? (close > open ? color.lime : close < open ? color.red : color.orange) : color.gray
plot(volume, "Volume", color=barColor, style=plot.style_columns)
plot(baseline, "Prior-bar average", color=color.blue, linewidth=2)
alertcondition(spike and barstate.isconfirmed, "Confirmed volume spike", "{{ticker}} volume exceeded the configured prior-bar baseline multiple.")
var table status = table.new(position.top_right, 1, 1)
if barstate.islast
table.cell(status, 0, 0, na(volume) ? "Volume unavailable" : not valid ? "Baseline unavailable or zero" : "Volume baseline available", text_color=chart.fg_color)
The 20-bar and 1.5-times defaults are illustrative. With a prior average of 100 units, 151 exceeds the threshold while exactly 150 does not. Those numbers explain the strict comparison; they are not a tested trading rule.
Green and red identify the price direction of a high-volume candle. Orange handles a candle whose open and close are equal. The colors do not label actual buying and selling volume.
Test the baseline and timing
Compare the plotted volume with TradingView's built-in volume display on the same chart. Then inspect the average on a few completed bars and confirm that it excludes the bar being tested. Initial history may be insufficient, which is why the status distinguishes an unavailable baseline.
During a live bar, accumulated volume can increase and the candle's direction can change. This example confirms the alert condition at bar close. Create a running alert in TradingView using the named condition and a suitable bar-close frequency; alertcondition() alone does not send notifications. Review the alert documentation and recreate saved alerts after relevant input or source changes.
Each completed bar above the threshold can qualify. The code does not require volume to cross from below the threshold on the previous bar, and it does not place trades.
Account for session patterns
A rolling average compares adjacent bars. It can mix opening activity with quieter periods or regular-session trading with overnight activity. Before calling a bar unusual, decide whether the comparison should use recent bars or matching times from previous sessions.
Record the session, timeframe, date range, and feed. Adjusting a threshold until it highlights a few attractive historical moves is not evidence that it generalizes. Compare a predefined rule on data that was not used to choose it and include failures in the count.
Related calculations have different meanings
ta.vwma(source, length) weights a source by volume. Pine also exposes Price Volume Trend as the ta.pvt series, not a ta.pvt() function call. These transform the supplied data; neither identifies the people behind a trade.
Price-row information is a separate topic. Pine now supports request.footprint() with plan and data constraints, so it is incorrect to say that scripts can only access aggregate bar volume. The footprint guide explains its classification method and API. A custom volume profile needs its own window and allocation rules.
Treat confirmation as a defined rule
A breakout accompanied by high volume satisfies a volume filter. It does not establish that the breakout is genuine, that institutions are buying, or that a reversal cannot follow. Specify the price breakout, confirmation time, exits, and costs before evaluating a strategy.
No AAPL earnings trade, NVDA forecast, or profitability result is established here. The deliverable is an inspectable volume calculation with explicit assumptions and missing-data behavior.
