Hi all
after some tinkering, I wanted to share some code that gives me what I'm looking for specifically. Try it out and if there are enhancements or errors, let me know. Otherwise, enjoy.
I use it against a watchlist of stocks primarily.
after some tinkering, I wanted to share some code that gives me what I'm looking for specifically. Try it out and if there are enhancements or errors, let me know. Otherwise, enjoy.
I use it against a watchlist of stocks primarily.
Code:
# RVOL (Relative Volume) - Watchlist Column (lighter / no daily-agg)
# Today's cumulative volume / Expected cumulative at SAME intraday bar.
# Primary: average of prior days at same bar index.
# Lightweight fallback: use a very short intraday SMA of today's cumVol slope (keeps numbers moving without daily aggregation).
# Made for tos by hboogie.
# Sept 2026
input lookbackDays = 5; # lighter than 20
input minSamples = 3; # fewer same-time samples required
input rthOpenTime = 0930;
input rthCloseTime = 1600;
def inRTH = SecondsFromTime(rthOpenTime) >= 0 and SecondsTillTime(rthCloseTime) >= 0;
def aggMS = GetAggregationPeriod();
def minsPerBar = aggMS / 60000;
def barsPerDay = Max(1, RoundDown(390 / minsPerBar, 0));
def ymd = GetYYYYMMDD();
def newDay = ymd <> ymd[1];
# Bar index within the RTH session
rec barInDay = if newDay then 0 else if inRTH then barInDay[1] + 1 else barInDay[1];
# Today's cumulative volume (RTH only)
rec cumVol = if newDay then 0 else if inRTH then cumVol[1] + volume else cumVol[1];
# Average of prior days' cumVol at SAME bar index (primary estimator)
def sumCum =
fold d = 1 to lookbackDays + 1
with s = 0
do s + (if barInDay > 0 then GetValue(cumVol, d * barsPerDay) else Double.NaN);
def cntCum =
fold d2 = 1 to lookbackDays + 1
with c = 0
do c + (if barInDay > 0 and !IsNaN(GetValue(cumVol, d2 * barsPerDay)) then 1 else 0);
def avgCumSameTime = if cntCum > 0 then sumCum / cntCum else Double.NaN;
# Lightweight fallback: extrapolate from recent intraday pace (avoids daily aggregation)
# Use short SMA of delta(cumVol) to estimate what cumVol "should" be by now.
def pace = if barInDay > 0 then cumVol - cumVol[1] else 0;
def paceSMA = Average(pace, 5); # 5-bar smoothing
def expectedFromPace = Max(0, paceSMA * barInDay); # naive linear accumulation
def expectedCum =
if cntCum >= minSamples and !IsNaN(avgCumSameTime) and avgCumSameTime > 0
then avgCumSameTime
else if expectedFromPace > 0 then expectedFromPace
else Double.NaN;
def rvolRaw = if expectedCum > 0 then cumVol / expectedCum else Double.NaN;
plot RV = Round(rvolRaw, 2);
# Black text for readability
RV.AssignValueColor(Color.BLACK);
# Your requested color map:
# <1 gray; [1,2) yellow; [2,3) light green; [3,5) orange; >=5 blue
AssignBackgroundColor(
if !inRTH or IsNaN(RV) then Color.GRAY
else if RV >= 5 then Color.BLUE
else if RV >= 3 then Color.ORANGE
else if RV >= 2 then Color.LIGHT_GREEN
else if RV >= 1 then Color.YELLOW
else Color.GRAY
);
RV.HideTitle();
RV.HideBubble();