This indicator, was designed to track momentum conditions often seen in volatile low-float stocks. It combines three key components that tend to drive explosive moves: gap percentage, relative volume (RVOL), and ATR expansion. Each factor contributes one point toward a composite “heat score” that ranges from 0 to 3. A score of 3 means all three conditions are firing at once: the stock is gapping up above a set threshold, trading with abnormal volume relative to its recent average, and showing volatility expansion (fast ATR significantly outpacing slow ATR). This creates a simple but powerful way to visualize when a stock is “heating up,” and it’s best applied to stocks that just released fresh news after hours or pre-market, since those catalysts often spark the exact kind of momentum this script is built to capture.
To keep things clear on the chart, the script smooths the score into a line called the, plotted at the bottom panel. Clouds help visually separate different levels of strength, while labels summarize the current readings for gap %, RVOL, and ATR ratio. A vertical green line will print when the Heat Line crosses into stronger territory, and an optional alert can be triggered when the score hits 3/3. This makes the Heat Meteor not just a momentum filter, but also a real-time scanner for conditions that often precede parabolic intraday moves. It’s especially useful for traders who like to focus on small-cap runners or news-driven plays and want a quick way to confirm when momentum is stacking in their favor.
To keep things clear on the chart, the script smooths the score into a line called the, plotted at the bottom panel. Clouds help visually separate different levels of strength, while labels summarize the current readings for gap %, RVOL, and ATR ratio. A vertical green line will print when the Heat Line crosses into stronger territory, and an optional alert can be triggered when the score hits 3/3. This makes the Heat Meteor not just a momentum filter, but also a real-time scanner for conditions that often precede parabolic intraday moves. It’s especially useful for traders who like to focus on small-cap runners or news-driven plays and want a quick way to confirm when momentum is stacking in their favor.
Ruby:
declare lower;
# ========================
# Low Float "Heat Metor"
# Created By TraderSam
# Coded 08/23/25
# ========================
# === Inputs ===
input rvolLen = 20; # Lookback length for avg volume
input rvolThresh = 3.0; # RVOL threshold
input atrFastLen = 5; # fast ATR length
input atrSlowLen = 20; # slow ATR length
input atrRatioThresh = 2.0; # ratio threshold (fast/slow)
input gapThreshPct = 7.0; # gapMomentum % threshold
input useLiveGap = yes;
input AlertOn = yes;
input smoothLen = 3; # smoothing length for Heat line
# === Basic Def ===
def c = close;
def h = high;
def o = open;
def l = low;
def v = volume;
def na = Double.NaN;
# === Daily references for Gap ===
def pcloseD = close(period = aggregationPeriod.DAY)[1];
def oD = open(period = aggregationPeriod.DAY);
# === Gap % ===
def lgpct = if pcloseD != 0 then 100 * (c - pcloseD) / pcloseD else 0; # live gap
def ogpct = if pcloseD != 0 then 100 * (oD - pcloseD) / pcloseD else 0; # open gap
def gpct = if useLiveGap then lgpct else ogpct;
def cGap = gpct >= gapThreshPct; # Condition: Gap over threshold
# === Relative Volume (RVOL) ===
def avgv = Average(v, rvolLen);
def rvol = if avgv > 0 then v / avgv else 0;
def cRVOL = rvol >= rvolThresh; # condition: rvol over threshold
# === ATR Expansion ===
def tr = TrueRange(h, c, l);
def atrf = MovingAverage(AverageType.WILDERS, tr, atrFastLen); # fast ATR
def atrs = MovingAverage(AverageType.WILDERS, tr, atrSlowLen); # slow ATR
def atrx = if atrs > 0 then atrf / atrs else 0;
def cATR = atrx >= atrRatioThresh; # condition: atr ratio over threshold
# === Composite Score (0–3) ===
def score = (if cGap then 1 else 0) + (if cRVOL then 1 else 0) + (if cATR then 1 else 0);
# === Smoothed Heat Line ===
def smoothHeat = Average(score, smoothLen);
plot HeatLine = smoothHeat;
HeatLine.SetDefaultColor(Color.cyan);
HeatLine.SetLineWeight(3);
# === Clouds ===
addcloud(1, 0, color.gray);
addcloud(2, 1, color.green);
addcloud(3, 2, color.dark_green);
# === Verticle Lines ===
def crossUp3 = smoothHeat[1] < 2 and smoothHeat >= 2;
AddVerticalLine(crossUp3, "BUY", Color.GREEN);
# === Labels ===
AddLabel(yes, "Heat " + Round(smoothHeat,1) + " | Gap " + AsText(Round(gpct, 1)) + "%" + " | RVOL " + AsText(Round(rvol, 2)) + " | ATRx " + AsText(Round(atrx, 2)), if smoothHeat >= 3 then Color.GREEN else if smoothHeat >= 2 then Color.DARK_GREEN else if smoothHeat >= 1 then Color.YELLOW else Color.GRAY);
# === Alerts ===
Alert(AlertOn and score >= 3, "Heat 3/3 (Gap+RVOL+ATR)", Alert.BAR, Sound.Ding);
Last edited: