How to Build a Relative Volume Screener in Python for Market Activity Analysis

How to Build a Relative Volume Screener in Python for Market Activity Analysis EduTechBuddy.com © edutechbuddy.com
How to Build a Relative Volume Screener in Python for Market Activity Analysis © edutechbuddy.com
Learn how to create a Python-based relative volume screener with pandas, understand the RVOL calculation, and recognize its practical limitations for market research.

Spotting unusual trading activity often comes down to a basic comparison: how does today’s volume stack up against a stock’s recent track record? Relative Volume (RVOL) answers this by showing the ratio between a session’s trading volume and its historical average over a set period. This method helps researchers flag instruments for further review, but making sense of the results means paying close attention to context and calculation choices.

What Is Relative Volume and Why Does It Matter?

Relative Volume, or RVOL, measures how a completed session’s trading volume compares to the average volume over a chosen number of previous sessions. For instance, if a stock’s average volume over the last 20 sessions is 500,000 shares and the latest session hits 1,500,000 shares, the RVOL comes out to 3.0. That means the stock traded three times its selected historical average. RVOL points to activity levels, not the reasons behind them, and the lookback period you pick can shift the outcome.

RVOL serves as a screening tool, not evidence of a fundamental catalyst or broad market significance. The U.S. Securities and Exchange Commission (SEC) has flagged in official filings that reported trading volumes may be influenced by fraudulent or manipulative activity, especially in digital-asset markets. Wash trading—repeatedly buying and selling the same asset to fake market activity—has triggered enforcement actions against those who artificially boost trading volumes. The SEC has warned that "any actual or perceived false trading" could hurt the value of digital assets, and that digital asset trading platforms might face wash trading risks. This highlights the need to approach volume metrics carefully and check the reliability of the underlying data (SEC Ripple XRP filing).

Preparing Synthetic Data for RVOL Calculation

To walk through the RVOL calculation, Python and pandas can generate a reproducible dataset. Imagine three hypothetical instruments—ALFA, BETA, and GAMA—each with 20 baseline sessions and one extra session for evaluation. The baseline volumes stay constant for clarity, though real market data usually fluctuates more.

import pandas as pd
rows = []
instruments = [
  ("ALFA", 500_000, 1_500_000),
  ("BETA", 800_000, 960_000),
  ("GAMA", 300_000, 780_000),
]
for symbol, baseline, latest in instruments:
  for session in range(1, 22):
    volume = baseline if session <= 20 else latest
    rows.append({
      "symbol": symbol,
      "session": session,
      "volume": volume,
    })
df = pd.DataFrame(rows)
df = df.sort_values(["symbol", "session"]).reset_index(drop=True)

This setup makes it easy to check the expected RVOL calculations. Each session number marks an ordered sequence, not a calendar date.

Calculating the Historical Average and RVOL

A frequent error is including the evaluated session in the historical average, which throws off the reference. To prevent this, shift the volume series by one before running a rolling mean. That way, only previous sessions count as the reference for each calculation.

df["avg_20_prev"] = (
  df.groupby("symbol")["volume"]
  .transform(lambda s: s.shift(1).rolling(window=20, min_periods=20).mean())
)

Once the historical average is set, calculate the RVOL for each session:

df["rvol"] = df["volume"] / df["avg_20_prev"]

To spot instruments with higher activity, filter for the latest session of each symbol and set a threshold. For example, picking RVOL values at or above 2.0 highlights instruments with at least double their historical average volume.

latest = df.groupby("symbol").tail(1).copy()
screened = latest[latest["rvol"] >= 2.0].sort_values("rvol", ascending=False)
print(latest[["symbol", "volume", "avg_20_prev", "rvol"]].to_string(index=False))

The resulting table displays:

SymbolCompleted-Session VolumePrevious 20-Session AverageRVOL
ALFA | 1,500,000 | 500,000 | 3.0
BETA | 960,000 | 800,000 | 1.2
GAMA | 780,000 | 300,000 | 2.6

With a 2.0 threshold, ALFA and GAMA move forward for further review. BETA, though above its average, falls short of the threshold. The threshold choice is a research call, not a fixed rule. No regulatory standard dictates a specific RVOL formula, lookback period, or threshold; these are user-driven heuristics and should not be seen as predictive guarantees.

Verifying the Calculation

Automated checks help confirm the calculation is accurate for the synthetic dataset. For example:

results = latest.set_index("symbol")["rvol"]
assert abs(results["ALFA"] - 3.0) < 1e-9
assert abs(results["BETA"] - 1.2) < 1e-9
assert abs(results["GAMA"] - 2.6) < 1e-9
assert set(screened["symbol"]) == {"ALFA", "GAMA"}
print("RVOL checks passed.")

These assertions show the calculations line up with expectations for the synthetic data. They do not check external data feeds or real market completeness.

Limitations and Interpretation of RVOL

RVOL is easy to compute, but understanding its meaning takes context. For instance, comparing a partial trading session’s volume to full-session averages can mislead. Differences in session coverage—like including or skipping extended-hours trading—also change the calculation. Shifts in instrument liquidity, corporate actions such as stock splits, or missing data can move the historical average and skew the ratio. Sometimes, a high RVOL points to an unusually low denominator instead of strong current activity. Researchers need to look into these factors before drawing conclusions from the ratio.

Volume data can also be warped by market-structure issues like wash trading, especially where surveillance and reporting standards differ. The SEC has taken action against digital asset market players for artificially boosting trading volumes through wash trading, which involves repeated transactions to manipulate prices or fake market activity. This regulatory history stresses the need for source and integrity checks on volume data, since a mathematically correct RVOL ratio can still mislead if the underlying data are inflated, duplicated, or unreliable. False or manipulated trading activity can erode confidence in an asset ecosystem and affect both analysis and market perception.

What to Do After Screening

RVOL screening flags instruments with unusual activity, but it does not reveal the reason for the volume. To dig deeper, compare the instrument’s activity with others in the same sector, review price and volume charts, and check how trading sessions and data coverage are defined. Documenting the observed conditions and uncertainties is key for structured market-data research. This approach matches the analytical focus of Ositrustees, where reproducibility and clear assumptions are central to effective screening workflows.

Moving from Prototype to Production

The example here is intentionally basic. A production-grade screener should validate instrument identifiers, keep session boundaries consistent, spot missing or duplicate data, handle zero or invalid averages, and document any adjustments or data changes. It also matters to separate daily and intraday RVOL measures, since these reflect different activity types. Recording the screening threshold, lookback period, and observation time makes results reproducible and meaningful.

For solid analysis, document the data vendor, exchange coverage, timestamp convention, session definition, corporate-action handling, and whether volume is consolidated or venue-specific. A production screener should separate completed-session volume from intraday partial volume, since comparing an incomplete current session with completed historical sessions can distort the RVOL ratio. High RVOL should not be taken as proof of informed trading or fundamental catalysts unless price movement, news, spreads, order-book conditions, and venue-level data are checked separately. As the SEC notes in risk disclosures, market participants may face exposure to wash trading, front-running, fraud, security failures, regulatory action, and trading suspensions (SEC Ripple XRP filing).

The pandas documentation points out that groupby operations and rolling calculations are essential for this kind of analysis in Python. All instruments and values in this tutorial are synthetic and meant for educational use only. This article does not offer investment advice.

Camila Ferreira Editor EduTechBuddy.com
Co-Founder

Camila Ferreira

Camila Ferreira is the Co-Founder of EduTechBuddy, where her editorial focus is programming education and practical software development skills. Her primary subjects include Python programming, Git version control, and the fundamental concepts beginners need to understand when working with code.