Volume and Volume-Based Indicators
Volume is the only series in an OHLCV bar that is not a price, and it is the one most often described in language it cannot support. This lesson separates what volume actually records from what people say it reveals, then builds the two derived measures AmiBroker provides and explains why their absolute values are meaningless.
What volume records, and what it does not
Section titled “What volume records, and what it does not”Volume is the number of shares, contracts or lots that changed hands during the bar. That is the entire content of the number.
In particular, it is not a measure of buying. Every executed trade has a buyer and a seller,
in equal size, at the same price. There is no such thing as “more buying than selling” in a
matched market — there is more aggression on one side, which is a real and different thing,
but volume alone cannot tell you which side that was. Order-flow tools that classify trades by
whether they hit the bid or lifted the offer exist, and Part 22 covers what AmiBroker offers
there; the Volume array is not one of them.
What high volume does say is that a lot of positions changed hands, so a lot of participants re-evaluated at those prices. That is a genuine and useful piece of context. It is a much weaker statement than “the smart money was accumulating”.
The problems with raw volume
Section titled “The problems with raw volume”It is not comparable between instruments. Ten million shares is enormous for one company and a quiet morning for another. Only volume relative to that instrument’s own history means anything.
It is not comparable across time within one instrument. Turnover in most markets has changed enormously over the decades, and a symbol’s typical volume today may be several times what it was fifteen years ago for reasons that have nothing to do with the current bar.
Split adjustment scales it. AmiBroker’s ASCII importer, when given an ADJCLOSE field,
computes a split factor from ADJCLOSE / CLOSE, multiplies the OHLC prices by it and divides
the volume by it. That is the right behaviour, and it means the volume figures in an adjusted
database are not the share counts that were actually printed on those days. If you are matching
against an exchange report, expect a difference.
The last intraday bar is partial. A live 5-minute bar has accumulated only part of its volume, so any “unusual volume” test evaluated intraday can be true at 09:35 and false at 09:40.
Different sources count different things. What a vendor reports as volume — which venues it consolidates, how it treats off-exchange prints — is a property of that vendor. Check its documentation rather than assuming, and never mix two sources in one study.
Average and relative volume
Section titled “Average and relative volume”Since only relative volume means anything, the first thing to build is a baseline. There is no
dedicated function for it; it is MA applied to the Volume array:
Fragment — not a complete formula
VolAvg = MA( Volume, 50 ); // mean volume over the last 50 barsRelVol = Volume / VolAvg; // today as a multiple of that meanUnusual = Volume > 2 * VolAvg; // the classic filterVolume distributions are heavily skewed — a handful of enormous days pull the mean up, so
“above average volume” happens on well under half of all bars. AmiBroker’s own documentation
leans on more robust alternatives in its examples. The Median page’s example is exactly this
filter, and the Percentile page’s is the same idea by rank:
Fragment — not a complete formula
// AmiBroker's own documented examples, both more robust than a mean for volume.AboveTypical = Volume > Median( Volume, 50 );InTopThird = Volume > Percentile( Volume, 100, 70 );Two documented details on those. Median( array, period ) returns the lower middle element
when the period is even — it does not average the two middle values; Percentile( array, period, 50 )
does that averaging, at the cost of being slower. And Percentile’s rank argument runs from
0 to 100, not 0 to 1, so Percentile( Volume, 100, 0.7 ) asks for the seven-tenths of one
per cent level, not the seventieth percentile. The page warns twice that the function is
computation intensive, so keep it out of large optimisation runs.
Guard the division, because MA is Null for the first periods - 1 bars and volume can be
zero:
Fragment — not a complete formula
VolAvg = MA( Volume, 50 );HasVolume = NOT IsNull( VolAvg ) AND VolAvg > 0;RelVol = IIf( HasVolume, Volume / VolAvg, 0 );OBV and accumulation/distribution
Section titled “OBV and accumulation/distribution”AmiBroker provides two cumulative volume lines. Both take no arguments at all:
Fragment — not a complete formula
Balance = OBV(); // On Balance Volume. OBV( 20 ) is an error.Flow = AccDist(); // Accumulation/Distribution line.The published construction of On Balance Volume is a running total: the bar’s volume is added when the close is higher than the previous close and subtracted when it is lower. The accumulation/distribution line weights each bar’s volume by where the close sat within the bar’s range before accumulating it, so a close at the high contributes its full volume and a close in the middle contributes little.
Why their level is meaningless
Section titled “Why their level is meaningless”This is the single most important practical fact about both functions.
They are cumulative from the first bar loaded. Not from the start of the year, not from some anchor date — from whatever bar happens to be the earliest one AmiBroker has in memory for that symbol. Change the database’s history depth, change the Analysis range, run the same formula on a symbol with a longer history, and the absolute value changes completely.
AccDist has an additional degenerate case: when a bar’s high equals its low, the “where did
the close sit in the range” term has a zero denominator. That happens on limit-locked futures,
on halted or suspended stocks, and on padded non-trading days.
Money Flow Index
Section titled “Money Flow Index”MFI( periods = 14 ) is the volume-weighted relative of RSI — bounded 0 to 100, default period
14, no input array. Its SEE ALSO points at rsi(), which tells you the intended mental model,
but the page does not document its internal smoothing. So do not claim MFI uses Wilder’s
smoothing; only RSI and ATR have that documented. Everything said about RSI’s saturation in
trends applies here too, with the added requirement that the volume it is weighting by has to be
real.
Price-volume claims, and how weak the evidence usually is
Section titled “Price-volume claims, and how weak the evidence usually is”Three claims dominate the literature:
- Volume “confirms” price — a move on high volume is more trustworthy than one on low volume.
- A breakout on high volume is more likely to hold than one on low volume.
- Extreme volume marks exhaustion and therefore turning points.
Every one of them is testable, and almost none of the writing that asserts them tests them. Look at what each statement leaves out.
“High volume” is defined after the fact. High relative to what baseline, over what window, measured as a multiple or a percentile? Change that definition and you change which bars qualify. If the definition is chosen after looking at the chart, the claim is unfalsifiable.
There is no horizon. “More likely to hold” over the next three days, three weeks or three years are entirely different assertions with entirely different answers.
There is no base rate. If breakouts hold 45 per cent of the time generally, then high-volume breakouts holding 48 per cent of the time is a small effect that needs a sample size before it means anything — and high-volume breakouts holding 45 per cent of the time means volume added nothing whatsoever.
The confound is enormous. High-volume bars are usually also high-range bars, and volatility clusters. A test that finds bigger subsequent moves after high-volume days may be measuring nothing but that clustering. Any honest volume study needs to ask whether the effect survives after controlling for the size of the move on the signal bar itself.
Part 12 contains a full reality check on high-volume breakouts, built with the Analysis tools you will have by then. What you can do now is stop repeating the claims as though they were settled, and notice how rarely the writing that asserts them names a universe, a period or a base rate.
Displaying volume in AmiBroker
Section titled “Displaying volume in AmiBroker”Volume needs its own pane, and it is conventionally a histogram. Plot’s colour argument
accepts an array as well as a single value, so you can colour each bar by whether the close
rose:
Fragment — not a complete formula
VolAvg = MA( Volume, 50 );BarTone = IIf( Close >= Ref( Close, -1 ), colorGreen, colorRed );
Plot( Volume, "Volume", BarTone, styleHistogram | styleThick );Plot( VolAvg, "50-bar mean", colorBlue, styleLine | styleThick );The average line matters more than the colouring. Colour alone is a poor carrier of meaning — some readers cannot distinguish those two hues — and the horizontal reference line is what actually lets you judge whether a bar was unusual, rather than whether it merely looks tall next to its neighbours.
For OBV and AccDist, give each its own pane and never label the axis as though the numbers
mean something. What you are reading is the slope.
Turning this into a testable question
Section titled “Turning this into a testable question”On my universe, over my chosen period, is the average absolute 10-day forward price change larger after bars whose volume exceeded three times its own 50-bar median than after all other bars — and does any difference survive when I compare only against other bars with a similar true range?
The first clause is the ordinary version of the test. The second clause is what makes it worth running: it is the attempt to separate a volume effect from the volatility clustering that would produce a positive answer even if volume carried no information at all. Designing that second comparison properly is harder than the first, and it is the kind of work that distinguishes a result you can rely on from one you merely like.
Volume counts what traded; it does not measure buying, because every trade has both sides. Raw
volume is not comparable between symbols, across eras, or across data sources, and split
adjustment rescales it. Build a baseline with MA( Volume, n ), and prefer Median or
Percentile because the distribution is skewed — both appear in AmiBroker’s own documented
examples. OBV() and AccDist() take no arguments and accumulate from the first bar loaded,
so their absolute level is an artefact of your database; read slope, never level. MFI is
volume-weighted momentum with an undocumented smoothing that needs real volume to mean anything.
And the popular price-volume claims are testable, rarely tested, and heavily confounded by the
fact that busy days are also volatile days.
Check your understanding
Sources for this lesson
7 verified · checked 2026-08-31
- 01AFL Function Reference — OBVamibroker.com/guide/afl/obv.html2026-08-31
- 02AFL Function Reference — AccDistamibroker.com/guide/afl/accdist.html2026-08-31
- 03AFL Function Reference — MFIamibroker.com/guide/afl/mfi.html2026-08-31
- 04AFL Function Reference — Medianamibroker.com/guide/afl/median.html2026-08-31
- 05AFL Function Reference — Percentileamibroker.com/guide/afl/percentile.html2026-08-31
- 06AmiBroker User's Guide — AFL language reference§ Predefined price array identifiersamibroker.com/guide/a_language.html2026-08-31
- 07AmiBroker User's Guide — ASCII importer§ ADJCLOSE and volume adjustmentamibroker.com/guide/d_ascii.html2026-08-31
Every technical claim on this page was checked against the official AmiBroker documentation on the date shown. Where the course disagrees with folklore, the source is how you can tell which one to trust.