Paste this code into the Pine Editor and add it to a standard candle chart. Select the direction rule and start timestamp. Per-bar mode is the default; enable cumulative mode to see the running sum. Only confirmed chart bars are plotted, so an open real-time bar stays blank until it closes.
Custom signed chart-bar volume. Flat comparison = zero; missing input invalidates the cumulative period. No lower-timeframe requests or trade-side data are used.pine
//@version=6
indicator("Signed bar volume: explicit rules", format=format.volume)
basis = input.string("Close vs open", "Direction", options=["Close vs open", "Close vs previous close"])
startTime = input.time(timestamp("01 Jan 2025 00:00 +0000"), "First included bar opening time")
resetDaily = input.bool(false, "Reset on exchange daily period")
showCumulative = input.bool(false, "Show cumulative instead of per-bar")
bool active = time >= startTime
bool dailyBoundary = timeframe.change("1D")
bool reset = active and (barstate.isfirst or not active[1] or (resetDaily and dailyBoundary))
float referencePrice = basis == "Close vs open" ? open : close[1]
bool valid = not na(close) and not na(referencePrice) and not na(volume) and volume >= 0
float signedVolume = valid ? (close > referencePrice ? volume : close < referencePrice ? -volume : 0.0) : na
var float total = 0.0
var bool complete = true
if reset
total := 0.0
complete := true
if active and barstate.isconfirmed
if valid
total += signedVolume
else
complete := false
float barValue = active and barstate.isconfirmed ? signedVolume : na
float cumulativeValue = active and barstate.isconfirmed and complete ? total : na
float value = showCumulative ? cumulativeValue : barValue
plot(value, "Signed volume", color=value >= 0 ? color.teal : color.red, style=plot.style_histogram)
hline(0, "Zero", color=color.gray)
bgcolor(active and barstate.isconfirmed and (not valid or (showCumulative and not complete)) ? color.new(color.orange, 85) : na, title="Unavailable calculation")