Strasmore Research
Learn am Matt ConnorBy Matt Connor · Updated 2026-08-22 · data as of August 22, 2026 · refreshed weekly

RVOL na Wetin? How to Read Relative Volume

RVOL na stock volume ÷ im 20-day average. Above 1 mean trading dey busier than normal. Learn intraday time-of-day RVOL and wetin count as high.

Relative volume (RVOL) dey measure how busy stock trading be compared with im recent normal: na the session share volume divide by the stock average daily volume, usually based on the last 20 sessions. RVOL of 1 mean ordinary day, 2 mean shares wey change hands na two times the usual amount, while 0.5 show say session dey run at half speed. Every figure for this page come from minute-level US market data, and exact query dey attached to each panel.

Relative volume na wetin? Plain-English meaning

Raw volume no mean much by itself: five million shares fit be very quiet day for mega-cap, but na event wey small-cap fit see only once every year. Relative volume makes comparison with the stock’s normal activity clear:

RVOL = the day’s volume ÷ the stock’s average daily volume (normally the last 20 sessions)

Make we use hypothetical example: if stock dey average 10 million shares per day and e prints 25 million before market close, e finish with RVOL of 2.5. (Print na trade wey dem report to consolidated tape, the market-wide record of executions. “The tape” na trader shorthand for that record.) The 20-session lookback na convention. Some platforms dey use 10, 30 or 50 days. E roughly represent one calendar month of trading. The window still dey reflect the exchange calendar quirks: holiday half-day dey add only small part of normal session volume to the average, and market holidays and early closes show where those ones dey happen.

Why traders dey watch relative volume?

RVOL na gauge for participation, e no be gauge for direction. High-RVOL days dey gather around events wey people fit identify, like earnings, index additions and headline news. When price move print on heavy volume, crowd dey behind am. But the same move with RVOL of 0.3 fit come from just small number of orders. Activity dey move together with tradability too. Across stocks, names wey dey trade thinly usually get the widest bid-ask spreads. Na the market makers wey quote both sides throughout the day dey post those spreads. For any one stock, quotes normally dey somewhat wider on quiet sessions than on busy ones. Volume also dey support VWAP, the volume-weighted average price, wey be another major volume-based reference.

How to calculate relative volume, and the time-of-day trap

The full-day calculation na one division: total volume for the session ÷ 20-session average daily volume. E only dey honest after market close. The trap na to calculate am mid-session: by 10:30 a.m., running total naturally be just part of any full-day figure, so even strong morning activity fit look weak. Intraday volume dey follow U-shape as the day dey move, and any intraday RVOL need start from that pattern.

Na this be the pattern, measured for SPY, the S&P 500 ETF: median shares traded per minute for each 30-minute clock bucket across the last 30 days of completed sessions, including extended hours from 4:00 a.m. to 8:00 p.m. Eastern Time.

QuerySPY: median shares wey trade per minute, by 30-minute clock bucket (ET, last 30 days, extended hours)
32 rows (showing 20)
ET timemedian minute volume k
04:000.6
04:300.3
05:000.3
05:300.3
06:000.4
06:300.5
07:001.1
07:301.6
08:002.2
08:303.3
09:004.7
09:30113.2
10:0082.9
10:3077.6
11:0064.3
11:3052.3
12:0049.3
12:3043.5
13:0043.4
13:3036.8
The exact SQL behind every number
SELECT formatDateTime(toStartOfInterval(toTimeZone(window_start, 'America/New_York'), INTERVAL 30 MINUTE), '%H:%i') AS et_time,
       round(quantileDeterministic(0.5)(toFloat64(volume), toUInt64(toUnixTimestamp(window_start))) / 1000, 1) AS median_minute_volume_k
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY'
  AND window_start >= now() - INTERVAL 30 DAY
  AND toDate(toTimeZone(window_start, 'America/New_York')) < toDate(toTimeZone(now(), 'America/New_York'))
GROUP BY et_time
HAVING et_time >= '04:00' AND et_time < '20:00'
ORDER BY et_time
Run am yourself

The 9:30 bucket, wey be the first half hour of regular trading, get median of 113.2 thousand shares per minute, compared with 4.7 thousand for the 9:00 premarket bucket just before am. The pace reduce to 43.5 thousand for the 12:30 bucket, then e build toward market close: 152.6 thousand for the 3:30 bucket, as trading dey move toward the closing auction, and well above the lunchtime low. After the 4:00 p.m. bell, per-minute pace drop sharply into after-hours trading.

Intraday relative volume: adjust am based on time of day

The correction dey change the denominator: compare today’s running total with the average running total for that same time on the clock. To do this, you need know the share of normal day’s volume wey don already complete at each time, based here on SPY’s last 20 completed sessions:

QuerySPY: average share of full-day volume wey don complete by each clock time (last 20 sessions)
ET checkpointavg % of day volume done
10:0020.7
12:0042.6
14:0057.2
15:3071.2
16:0087.5
The exact SQL behind every number
WITH per_min AS (
    SELECT toDate(toTimeZone(window_start, 'America/New_York')) AS et_date,
           formatDateTime(toTimeZone(window_start, 'America/New_York'), '%H:%i') AS et_min,
           sum(toFloat64(volume)) AS v
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker = 'SPY'
      AND window_start >= now() - INTERVAL 45 DAY
      AND toDate(toTimeZone(window_start, 'America/New_York')) < toDate(toTimeZone(now(), 'America/New_York'))
    GROUP BY et_date, et_min
),
last20 AS (
    SELECT DISTINCT et_date FROM per_min ORDER BY et_date DESC LIMIT 20
)
SELECT checkpoint AS et_checkpoint,
       round(avg(share) * 100, 1) AS avg_pct_of_day_volume_done
FROM (
    SELECT et_date,
           checkpoint,
           sumIf(v, et_min < checkpoint) / sum(v) AS share
    FROM (
        SELECT et_date, et_min, v, arrayJoin(['10:00', '12:00', '14:00', '15:30', '16:00']) AS checkpoint
        FROM per_min
        WHERE et_date IN (SELECT et_date FROM last20)
    )
    GROUP BY et_date, checkpoint
)
GROUP BY checkpoint
ORDER BY checkpoint
Run am yourself

By 10:00 a.m., after half an hour of regular trading, SPY normally don print just 20.7% of the full-day volume wey e go eventually reach. By noon, na 42.6%. By 2:00 p.m., na 57.2%. By 3:30 p.m., e still be only 71.2%. Even when the 4:00 p.m. closing bell ring, total volume na 87.5%. Everything else dey get reported at or after 16:00. Most of am enter the tape during the first few minutes after the bell, when the closing auction and other end-of-day trades happen. The after-hours session itself dey far thinner.

This one match the sharp drop for the chart above. Per-minute trading pace collapse at the bell, even though meaningful part of the day’s total still dey get reported. Time-adjusted morning RVOL divides today’s cumulative volume by the 20-day average multiplied by the checkpoint share.

One caveat: this schedule na SPY own. Each stock get its own clock. The worked example below measures one particular name’s.

One worked example: real heavy-volume session (MU)

June 2026 heavy month for Micron, the MU June 2026 deep-dive dey show the full tape. Na the month’s single biggest-volume session be this, with RVOL math done for both methods:

QueryMU, the session wey get the biggest volume for June 2026: time-adjusted vs. naive RVOL, plus the full-day figure
session datevol by 1030 mavg vol by 1030 mrvol 1030 adjustedrvol 1030 naivesession volume mtrailing ADV mrvol full day
2026-06-2532.817.31.90.6477.2511.5
The exact SQL behind every number
WITH mu_daily AS (
    SELECT toDate(toTimeZone(window_start, 'America/New_York')) AS et_date,
           sum(toFloat64(volume)) AS day_volume,
           sumIf(toFloat64(volume), formatDateTime(toTimeZone(window_start, 'America/New_York'), '%H:%i') < '10:30') AS vol_by_1030
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker = 'MU'
      AND window_start >= toDateTime('2026-04-15 00:00:00', 'America/New_York')
      AND window_start < toDateTime('2026-07-01 00:00:00', 'America/New_York')
    GROUP BY et_date
    HAVING day_volume > 1000000
),
biggest AS (
    SELECT et_date, day_volume, vol_by_1030
    FROM mu_daily
    WHERE et_date >= toDate('2026-06-01') AND et_date <= toDate('2026-06-30')
    ORDER BY day_volume DESC
    LIMIT 1
),
trailing AS (
    SELECT sum(day_volume) / 20 AS adv, sum(vol_by_1030) / 20 AS avg_by_1030
    FROM (
        SELECT day_volume, vol_by_1030
        FROM mu_daily
        WHERE et_date < (SELECT et_date FROM biggest)
        ORDER BY et_date DESC
        LIMIT 20
    )
)
SELECT formatDateTime((SELECT et_date FROM biggest), '%Y-%m-%d') AS session_date,
       round((SELECT vol_by_1030 FROM biggest) / 1e6, 1) AS vol_by_1030_m,
       round((SELECT avg_by_1030 FROM trailing) / 1e6, 1) AS avg_vol_by_1030_m,
       round((SELECT vol_by_1030 FROM biggest) / (SELECT avg_by_1030 FROM trailing), 1) AS rvol_1030_adjusted,
       round((SELECT vol_by_1030 FROM biggest) / (SELECT adv FROM trailing), 2) AS rvol_1030_naive,
       round((SELECT day_volume FROM biggest) / 1e6, 1) AS session_volume_m,
       round((SELECT adv FROM trailing) / 1e6, 1) AS trailing_adv_m,
       round((SELECT day_volume FROM biggest) / (SELECT adv FROM trailing), 1) AS rvol_full_day
Run am yourself

MU’s biggest session for the month happen on 2026-06-25. By 10:30 a.m. that day, 32.8 million shares don trade, compared with average of 17.3 million by that same time across the previous 20 sessions. That one give time-adjusted RVOL of 1.9. If you divide the morning total by the full-day average of 51 million instead, the naive reading be 0.64: a below-average day, even though the morning pace dey almost twice the normal rate. The session close with 77.2 million shares, giving full-day RVOL of 1.5.

That closing figure fit look small beside screenshots of movers wey trade at ten-times-average volume. Whether e really small na matter for distribution, and we go measure that next.

Wetín count as high relative volume?

Trading forums dey use thresholds like “RVOL above two na high.” But here na the measured version: we calculate full-day RVOL for every US-listed stock and ETF wey get 20-day average daily volume above 5 million shares, plus full history for 20 previous sessions. Then we rank am by percentile across the group for the latest completed session for our data. One thing about the label: the screen dey count shares, no be dollar value. So this high-volume group cover mega-caps and ETFs down to cheap, high-churn small-caps. High share volume no mean say the instrument easy to trade.

QueryFull-day RVOL percentiles across high-volume US stocks and ETFs (20-day ADV above 5M shares), latest completed session
percentilervol
p100.08
p250.57
p50 (median)0.86
p751.2
p901.69
p993.43
The exact SQL behind every number
WITH daily AS (
    SELECT ticker,
           toDate(toTimeZone(window_start, 'America/New_York')) AS et_date,
           toFloat64(sum(volume)) AS day_volume
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE window_start >= now() - INTERVAL 40 DAY
      AND toDate(toTimeZone(window_start, 'America/New_York')) < toDate(toTimeZone(now(), 'America/New_York'))
    GROUP BY ticker, et_date
),
spy_days AS (
    SELECT et_date,
           day_volume,
           avg(day_volume) OVER (ORDER BY et_date ROWS BETWEEN 20 PRECEDING AND 1 PRECEDING) AS prior_avg
    FROM daily
    WHERE ticker = 'SPY' AND day_volume > 10000000
),
sessions AS (
    SELECT et_date FROM spy_days
),
latest AS (
    SELECT max(et_date) AS d FROM spy_days WHERE prior_avg > 0 AND day_volume >= 0.6 * prior_avg
),
prior20 AS (
    SELECT et_date FROM sessions WHERE et_date < (SELECT d FROM latest) ORDER BY et_date DESC LIMIT 20
),
rvols AS (
    SELECT ticker, day_vol / adv20 AS rvol
    FROM (
        SELECT ticker,
               sumIf(day_volume, et_date = (SELECT d FROM latest)) AS day_vol,
               sumIf(day_volume, et_date IN (SELECT et_date FROM prior20)) / 20 AS adv20,
               countIf(day_volume > 0 AND et_date IN (SELECT et_date FROM prior20)) AS sessions_traded
        FROM daily
        WHERE ticker NOT IN ('SPCX')
        GROUP BY ticker
        HAVING adv20 > 5000000 AND day_vol > 0 AND sessions_traded = 20
    )
)
SELECT pair.1 AS percentile,
       round(pair.2, 2) AS rvol
FROM (
    SELECT arrayJoin(arrayZip(['p10', 'p25', 'p50 (median)', 'p75', 'p90', 'p99'], quantilesExact(0.1, 0.25, 0.5, 0.75, 0.9, 0.99)(rvol))) AS pair
    FROM rvols
)
ORDER BY percentile
Run am yourself

The median name for this high-volume group traded at 0.86 times its own 20-day average. Nine out of ten names came below 1.69, and only one out of every hundred passed 3.43. Put MU’s session from the previous section beside this table and e no go look modest again. Even busy names spend most days near their own average. Multiples of that average dey rare.

The bottom tail matter too. The 10th percentile sit at 0.08. Readings this low usually show say one very large session still dey inside the stock’s 20-day average. After a spike, that inflated denominator fit hold RVOL down for weeks. The window get memory, both ways.

One warning: this na cross-section from one session only. Percentiles fit shift from day to day. Market-wide event days, like index rebalances and option expirations, fit lift the whole curve.

Which stocks get unusual volume? The RVOL leaderboard

Na the same universe, but dem rank am (the regular weekly version dey for unusual volume stocks this week): the ten highest full-day RVOL readings for the 2026-08-21 session among names wey dey average above 5 million shares per day. Na the stocks wey screener go flag as unusual volume. The screen require full 20 prior sessions. New listings never get meaningful 20-day average, so without this rule dem fit fill the board with bad results.

QueryTop 10 by full-day RVOL: latest completed session (20-day ADV above 5M shares, full history required)
tickersession datesession volume mADV 20d mrvol
HOWL2026-08-212655.350
CAN2026-08-2193118.5
LGCL2026-08-2188.113.16.8
MRNA2026-08-2188.1165.5
PURR2026-08-2136.79.83.8
BABA2026-08-2132.18.73.7
COIN2026-08-2124.57.13.4
BITX2026-08-2126.78.33.2
GOSS2026-08-21130.9413.2
TEM2026-08-2116.25.13.2
The exact SQL behind every number
WITH daily AS (
    SELECT ticker,
           toDate(toTimeZone(window_start, 'America/New_York')) AS et_date,
           toFloat64(sum(volume)) AS day_volume
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE window_start >= now() - INTERVAL 40 DAY
      AND toDate(toTimeZone(window_start, 'America/New_York')) < toDate(toTimeZone(now(), 'America/New_York'))
    GROUP BY ticker, et_date
),
spy_days AS (
    SELECT et_date,
           day_volume,
           avg(day_volume) OVER (ORDER BY et_date ROWS BETWEEN 20 PRECEDING AND 1 PRECEDING) AS prior_avg
    FROM daily
    WHERE ticker = 'SPY' AND day_volume > 10000000
),
sessions AS (
    SELECT et_date FROM spy_days
),
latest AS (
    SELECT max(et_date) AS d FROM spy_days WHERE prior_avg > 0 AND day_volume >= 0.6 * prior_avg
),
prior20 AS (
    SELECT et_date FROM sessions WHERE et_date < (SELECT d FROM latest) ORDER BY et_date DESC LIMIT 20
)
SELECT ticker,
       formatDateTime((SELECT d FROM latest), '%Y-%m-%d') AS session_date,
       round(day_vol / 1e6, 1) AS session_volume_m,
       round(adv20 / 1e6, 1) AS adv_20d_m,
       round(day_vol / adv20, 1) AS rvol
FROM (
    SELECT ticker,
           sumIf(day_volume, et_date = (SELECT d FROM latest)) AS day_vol,
           sumIf(day_volume, et_date IN (SELECT et_date FROM prior20)) / 20 AS adv20,
           countIf(day_volume > 0 AND et_date IN (SELECT et_date FROM prior20)) AS sessions_traded
    FROM daily
    WHERE ticker NOT IN ('SPCX')
    GROUP BY ticker
    HAVING adv20 > 5000000 AND day_vol > 0 AND sessions_traded = 20
)
ORDER BY rvol DESC, ticker
LIMIT 10
Run am yourself

HOWL dey top the board. The stock print 265 million shares, against 20-day average of 5.3 million. Its RVOL na 50. Every row pass its own average. Boards like this dey move away from household mega-caps. To double an already-enormous average, the stock need trade extraordinary number of shares. But smaller name fit multiply its trading volume for one session.

Data notes: how we choose sessions and exclusions

Both ranked tables use the same universe and the same session rule. Candidate session only count as complete after SPY tape for that date reach at least 60% of SPY own prior-20-session average volume. Newest day data dey arrive with delay. This check stop partially loaded day from looking like finished session. Both tables also exclude one symbol wey exchanges recently assign to a new listing. Vendor feeds carry the history of two different companies under that ticker, so its 20-day average no be meaningful baseline. The exclusion list inside the SQL dey stay aligned with our symbol-identity checks for every refresh. Any new reused symbol wey dem flag, we add am the same way.

FAQ

RVOL number wey good na which one?

Official threshold no dey. For high-volume US stocks wey our data measure during the latest completed session, the median stock trade at 0.86 times its 20-day average, the 90th percentile na 1.69, and the 99th na 3.43.

Wetin RVOL of 2 mean?

The stock don trade two times its average volume for the measured window, usually the trailing 20 sessions. The time of day matter: 2 compared with the average for the same time of day na strong mid-session reading; 2 at the close mean say the day trade at double the normal pace.

How una dey calculate relative volume intraday?

Divide today’s cumulative volume by the average cumulative volume for that same clock time across your lookback window. If you divide mid-morning total by full-day average, you go understate the reading badly. By 10:00 a.m., SPY usually don complete only 20.7% of its final day volume.

Relative volume include premarket and after-hours trading?

Platform conventions dey differ. This page count every minute bar for the Eastern Time calendar day, including extended hours. For SPY, premarket contribution small clearly: median of 4.7 thousand shares per minute for the 9:00 bucket, compared with 113.2 thousand just after the open.

High relative volume bullish or bearish?

None of the two. RVOL measure participation, no be direction. Heavy tape dey show for stock’s best days and worst days alike. Historically, high-RVOL sessions dey happen together with earnings, index changes and headline news. The number only show say crowd show up; e no say which direction dem dey support.


Every panel above get the exact SQL wey produce am. Open one, put your own ticker, and measure RVOL for the names wey you actually trade on the Strasmore terminal.

#relative volume#rvol#unusual volume#volume#liquidity#market structure