๐Ÿ“‰ Metro Heartbeat Advance โ€“ Momentum State Indicator (StepRSI-Based)

โ€”

by

By Sharma Research
Concept inspired by Welles Wilder Jr. (RSI foundations)


Metro Heartbeat Advance is a momentum state indicator designed to distinguish real momentum regimes from short-lived fluctuations.

Most momentum indicatorsโ€”including RSIโ€”react to every price change. While this makes them responsive, it also makes them noisy. In sideways or choppy markets, this noise often produces frequent flips that look like momentum but fail to sustain.

Metro Heartbeat Advance addresses this problem by focusing on momentum continuity, not momentary spikes.

Instead of asking โ€œIs momentum high or low?โ€, it asks a more useful question:

Is momentum behaving consistently enough to be trusted?


๐Ÿ” Why Traditional Momentum Often Misleads

Classic RSI-based systems face two structural issues:

  • RSI reacts instantly to price changes, even if the move lacks follow-through

  • Short-term oscillations can look like momentum shifts but quickly reverse

This creates false momentumโ€”signals that appear strong for a candle or two but collapse once volatility fades.

Metro Heartbeat Advance is designed to filter out these short-lived impulses and highlight only sustained changes in momentum behavior.


๐Ÿง  Core Idea: Momentum Has a Rhythm

At its heart, this indicator treats momentum like a heartbeat:

  • A single spike does not indicate health

  • Consistency and rhythm matter more than intensity

To achieve this, the indicator transforms RSI into a step-based structure that only moves when momentum meaningfully shifts.


โš™๏ธ How Metro Heartbeat Advance Works

1๏ธโƒฃ Flexible RSI Foundation

The indicator begins with an RSI core, allowing the user to choose between:

  • Regular RSI

  • Wilderโ€™s RSI (original smoothing method)

  • RSX (smoothed RSI variant)

  • Cuttler RSI

This flexibility allows users to adapt the indicator to different instruments and timeframes, while maintaining a consistent logic layer above.


2๏ธโƒฃ StepRSI Transformation (Noise Reduction Layer)

Instead of plotting raw RSI directly, Metro Heartbeat Advance converts RSI into two stepped lines:

  • StepRSI Fast โ†’ responds quicker to momentum changes

  • StepRSI Slow โ†’ represents broader momentum structure

Each line moves only in predefined steps, using a clamp mechanism:

  • Minor RSI fluctuations are ignored

  • Momentum must move meaningfully to cause a step

๐Ÿ‘‰ Result: smoother momentum behavior without lagging excessively.

This is not smoothing for aestheticsโ€”it is behavioral filtering.


3๏ธโƒฃ Momentum State Definition (Fast vs Slow)

Momentum state is defined simply and clearly:

  • Fast > Slow โ†’ Bullish momentum regime

  • Fast < Slow โ†’ Bearish momentum regime

Rather than firing signals on every RSI cross, the indicator establishes regime bias first.

This encourages users to think in terms of states, not entries.


โค๏ธ The Heartbeat Layer (Regime Confirmation)

The optional Heartbeat logic adds a second layer of discipline.

It can be configured to:

  • Require fresh cross confirmation (signals only on regime changes)

  • Invert logic for alternative interpretations

  • Completely disable heartbeat filtering if desired

When enabled, signals are generated only when momentum transitions from one regime to another, not while it oscillates inside the same state.

This dramatically reduces signal clutter and helps isolate meaningful momentum shifts.


๐ŸŽจ Visual Interpretation

Metro Heartbeat Advance is designed to be visually intuitive:

  • RSI and StepRSI lines are plotted in a dedicated pane

  • Overbought and oversold levels provide context, not triggers

  • Heartbeat signals appear as directional markers

  • Optional background shading highlights the active momentum regime

The goal is not to overwhelm, but to let the chart explain itself.


๐Ÿšจ About Changes (Educational Use Only)

Any directional markers or transitions shown by this indicator are intended for learning, research, and backtesting purposes only.

They are not buy/sell recommendations.

Momentum indicators describe behavior, not outcomes.
They are best used in combination with structure, trend context, and risk management.


๐Ÿ“š Concept Inspiration

The foundation of this indicator traces back to the work of Welles Wilder Jr., creator of RSI and Wilderโ€™s smoothing techniques.

Metro Heartbeat Advance builds upon these ideas by:

  • Introducing step-based momentum control

  • Separating regime identification from signal timing

  • Emphasizing momentum continuity over short-term reactions

It is not a replacement for RSI, but an evolution in how RSI is interpreted.


Written in Pine Script v5 for TradingView
๐Ÿ“Œ Copy the code below and paste it intoย TradingView โ†’ Pine Editor โ†’ Save & Add to Chart

//@version=5
// Metro Heartbeat Advance by SharmaResearch.com
// Concept credit: Welles Wilder Jr. (RSI + Wilder smoothing foundations)
//
// How this works (quick intro):
// This indicator is a momentum-state system built on an RSI core (selectable: Regular/Wilder/RSX/Cuttler).
// RSI values are transformed into two stepped lines (Fast & Slow) using a step-clamp mechanism to reduce noise
// and highlight sustained shifts in momentum. Trend state is defined by Fast vs Slow (bullish when Fast > Slow,
// bearish when Fast < Slow). The optional โ€œHeartbeatโ€ layer can invert logic and/or require fresh cross
// confirmation so signals fire only on regime changes. Visuals support arrows in pane, main-chart markers,
// or candle coloring, with optional background highlighting of the active heartbeat state.

indicator(“Metro Heartbeat Advance by SharmaResearch.com (Concept: Welles Wilder Jr.) โ€” StepRSI Fast/Slow + Heartbeat Confirmation”,
shorttitle=”MetroHB+”,
overlay=false)

// โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
// Inputs
// โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
rsiType = input.string(“Regular”, “RSI Type”, options=[“Regular”, “Wilders”, “RSX”, “Cuttler”])
periodRSI = input.int(14, “RSI Period”)
stepFast = input.int(5, “Step Size Fast”)
stepSlow = input.int(15, “Step Size Slow”)
overSold = input.float(10, “Oversold Level”)
overBought = input.float(90, “Overbought Level”)
useHeartbeat = input.bool(true, “Use Heartbeat?”)
crossConfirm = input.bool(true, “Cross confirmation?”)
inverseHB = input.bool(false, “Inverse Heartbeat?”)
showBG = input.bool(true, “Show Background?”)

// โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
// Helpers
// โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
safeDiv(n, d, fallback) =>
d == 0.0 ? fallback : n / d

// RSX
getRSX(src, len) =>
var float smooth = na
var float momentum = na
var float absmomentum = na
alpha = 2.0 / (len + 1.0)
mom = ta.change(src)
absm = math.abs(mom)
smooth := alpha * mom + (1 – alpha) * nz(smooth[1])
momentum := alpha * smooth + (1 – alpha) * nz(momentum[1])
absmomentum := alpha * absm + (1 – alpha) * nz(absmomentum[1])
rsx_raw = safeDiv(momentum, absmomentum, 0.0)
math.max(math.min(50 * (rsx_raw + 1), 100), 0)

// Cuttler RSI
getCuttlerRSI(src, len) =>
ch = ta.change(src)
pos = math.sum(math.max(ch, 0), len)
neg = math.sum(math.max(-ch, 0), len)
rs = neg == 0.0 ? 999999.0 : pos / neg
100.0 – (100.0 / (1.0 + rs))

// Wilders RSI
getWildersRSI(src, len) =>
ch = ta.change(src)
gain = math.max(ch, 0)
loss = math.max(-ch, 0)
avgG = ta.rma(gain, len)
avgL = ta.rma(loss, len)
rs = safeDiv(avgG, avgL, 999999.0)
100.0 – (100.0 / (1.0 + rs))

// โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
// RSI Type Switch
// โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
src = close
rsiLine = switch rsiType
“Wilders” => getWildersRSI(src, periodRSI)
“RSX” => getRSX(src, periodRSI)
“Cuttler” => getCuttlerRSI(src, periodRSI)
=> ta.rsi(src, periodRSI)

// โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
// StepRSI Fast / Slow
// โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
var float stepRSIFast = na
var float stepRSISlow = na

stepRSIFast := na(stepRSIFast[1]) ? rsiLine :
math.max(math.min(stepRSIFast[1], rsiLine + stepFast), rsiLine – stepFast)

stepRSISlow := na(stepRSISlow[1]) ? rsiLine :
math.max(math.min(stepRSISlow[1], rsiLine + stepSlow), rsiLine – stepSlow)

// โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
// Heartbeat Logic
// โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
trend = stepRSIFast > stepRSISlow ? 1 : stepRSIFast < stepRSISlow ? -1 : 0

basicLong = trend == 1
basicShort = trend == -1

hbLong = useHeartbeat ? (inverseHB ? basicShort : basicLong) : false
hbShort = useHeartbeat ? (inverseHB ? basicLong : basicShort) : false

hbLongFinal = crossConfirm ? ta.crossover(stepRSIFast, stepRSISlow) : hbLong
hbShortFinal = crossConfirm ? ta.crossunder(stepRSIFast, stepRSISlow) : hbShort

// โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
// Plots (Pane)
// โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
plot(rsiLine, “RSI”, color=color.orange, linewidth=1)
plot(stepRSIFast, “StepRSI Fast”, color=color.aqua, linewidth=1)
plot(stepRSISlow, “StepRSI Slow”, color=color.fuchsia, linewidth=1)

hline(overBought, “Overbought”, color=color.red, linestyle=hline.style_dotted)
hline(overSold, “Oversold”, color=color.green, linestyle=hline.style_dotted)

plot(hbLongFinal ? 1 : na, “Heartbeat Long”, color=color.lime, style=plot.style_columns)
plot(hbShortFinal ? -1 : na, “Heartbeat Short”, color=color.red, style=plot.style_columns)

bgcolor(showBG ? (hbLongFinal ? color.new(color.lime, 85) : hbShortFinal ? color.new(color.red, 85) : na) : na)


๐Ÿ“„ Important Disclosures

๐Ÿ“ข Disclaimer: This indicator and article are for informational and educational purposes only. Nothing herein constitutes a buy or sell recommendation. I may or may not be holding a position in the securities discussed.

๐Ÿง‘โ€๐Ÿ’ผ Rajneesh Sharma is a SEBI-registered Research Analyst
Reg. No.: INH000020332

๐Ÿ“„ Investments are subject to market risks. Read all related documents carefully before investing.
๐Ÿ“ฉ Investor Charter & SCORES grievance redressal information is available on our blog.