Indicator · Pine Script v5 · Own pane

15m Reversal Detector

by caizongxun

A separate-pane tool that looks for potential reversals by combining momentum, volume and candle shape.

View on GitHub

GitHub stars1on the repository
Pine versionv5runs as is
Lines of code208
Settings10inputs
LicenceMIT
Last update8 months ago21 Feb 2026

Add It to Your TradingView Chart

  1. 1Copy the scriptPress Copy script above, or the copy button on the code below.
  2. 2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
  3. 3Paste over the templateCreate a new indicator, select all of the template text and paste. Press Save and give it a name.
  4. 4Add it to the chartPress Add to chart, then adjust the settings with the gear icon next to its name.

Source Code

208 lines of Pine Script v5 from pine scripts/15m_Reversal_Momentum_Volume.pine, published under MIT. Keep the author's credit and licence lines when you reuse it.

15m_Reversal_Momentum_Volume.pine
//@version=5
indicator("15m Reversal Detector [Momentum+Volume]", shorttitle="Rev Detector", overlay=false)

// ==========================================
// THEORY: Multi-Factor Reversal Detection
// ==========================================
// A true reversal requires 3 confirmations:
// 1. MOMENTUM Divergence: Price makes new extreme but momentum weakens (RSI/MACD divergence)
// 2. PRICE ACTION: Rejection candles (long wicks, engulfing, pin bars)
// 3. VOLUME Anomaly: Climax volume (exhaustion) or Volume Drying (loss of conviction)

// ==========================================
// 1. INPUTS
// ==========================================
grp_mom = "Momentum Settings"
rsi_len = input.int(14, "RSI Length", group=grp_mom)
macd_fast = input.int(12, "MACD Fast", group=grp_mom)
macd_slow = input.int(26, "MACD Slow", group=grp_mom)
macd_sig = input.int(9, "MACD Signal", group=grp_mom)

grp_vol = "Volume Settings"
vol_ma_len = input.int(20, "Volume MA Length", group=grp_vol)
vol_spike_mult = input.float(2.0, "Volume Spike Multiplier", group=grp_vol)

grp_price = "Price Action Settings"
wick_ratio = input.float(0.6, "Min Wick/Body Ratio for Rejection", group=grp_price, tooltip="0.6 means wick must be 60% of total candle range")
bb_len = input.int(20, "BB Length (for Extreme Detection)", group=grp_price)
bb_mult = input.float(2.0, "BB Mult", group=grp_price)

grp_div = "Divergence Settings"
lookback_div = input.int(5, "Pivot Lookback for Divergence", group=grp_div)

// ==========================================
// 2. MOMENTUM INDICATORS
// ==========================================

// RSI
rsi = ta.rsi(close, rsi_len)

// MACD
[macd_line, signal_line, hist] = ta.macd(close, macd_fast, macd_slow, macd_sig)

// Stochastic RSI (faster momentum)
stoch_k = ta.stoch(close, high, low, 14)

// ==========================================
// 3. VOLUME ANALYSIS
// ==========================================

// Volume MA
vol_ma = ta.sma(volume, vol_ma_len)

// Volume States
is_vol_spike = volume > vol_ma * vol_spike_mult  // Climax volume (exhaustion)
is_vol_dry = volume < vol_ma * 0.5  // Drying up (no conviction)

// Volume Delta (Buying vs Selling Pressure Proxy)
// Using close vs open to estimate directional pressure
vol_delta = (close > open) ? volume : -volume
vol_delta_ma = ta.sma(vol_delta, 10)

// ==========================================
// 4. PRICE ACTION PATTERNS
// ==========================================

// Bollinger Bands (for extreme price detection)
basis = ta.sma(close, bb_len)
dev = ta.stdev(close, bb_len)
upper_bb = basis + dev * bb_mult
lower_bb = basis - dev * bb_mult

at_top = close >= upper_bb  // Price at statistical extreme (top)
at_bottom = close <= lower_bb  // Price at statistical extreme (bottom)

// Candle Anatomy
body = math.abs(close - open)
range_candle = high - low
upper_wick = high - math.max(close, open)
lower_wick = math.min(close, open) - low

// Rejection Patterns
bearish_rejection = upper_wick > body * wick_ratio and close < open  // Long upper wick + red body
bullish_rejection = lower_wick > body * wick_ratio and close > open  // Long lower wick + green body

// Engulfing (Strong reversal pattern)
bullish_engulf = close > open and close[1] < open[1] and close > open[1] and open < close[1]
bearish_engulf = close < open and close[1] > open[1] and close < open[1] and open > close[1]

// ==========================================
// 5. DIVERGENCE DETECTION
// ==========================================

// Find Recent Pivot Highs/Lows in PRICE
ph_price = ta.pivothigh(high, lookback_div, lookback_div)
pl_price = ta.pivotlow(low, lookback_div, lookback_div)

// Find Recent Pivot Highs/Lows in RSI
ph_rsi = ta.pivothigh(rsi, lookback_div, lookback_div)
pl_rsi = ta.pivotlow(rsi, lookback_div, lookback_div)

// Store last pivots
var float last_ph_price = na
var float last_pl_price = na
var float last_ph_rsi = na
var float last_pl_rsi = na
var int last_ph_bar = na
var int last_pl_bar = na

if not na(ph_price)
    last_ph_price := ph_price
    last_ph_rsi := rsi[lookback_div]
    last_ph_bar := bar_index - lookback_div
    
if not na(pl_price)
    last_pl_price := pl_price
    last_pl_rsi := rsi[lookback_div]
    last_pl_bar := bar_index - lookback_div

// Bearish Divergence: Price makes Higher High, but RSI makes Lower High
bearish_div = false
if not na(last_ph_price) and not na(last_ph_rsi)
    if high > last_ph_price and rsi < last_ph_rsi and bar_index - last_ph_bar < 30
        bearish_div := true

// Bullish Divergence: Price makes Lower Low, but RSI makes Higher Low
bullish_div = false
if not na(last_pl_price) and not na(last_pl_rsi)
    if low < last_pl_price and rsi > last_pl_rsi and bar_index - last_pl_bar < 30
        bullish_div := true

// ==========================================
// 6. REVERSAL CONFLUENCE SCORE
// ==========================================

// Bearish Reversal Score (0-10)
bear_score = 0
bear_score := bear_score + (at_top ? 2 : 0)  // At overbought zone
bear_score := bear_score + (bearish_rejection or bearish_engulf ? 3 : 0)  // Strong price rejection
bear_score := bear_score + (bearish_div ? 3 : 0)  // Momentum divergence
bear_score := bear_score + (is_vol_spike ? 1 : 0)  // Volume climax
bear_score := bear_score + (rsi > 70 ? 1 : 0)  // RSI overbought

// Bullish Reversal Score (0-10)
bull_score = 0
bull_score := bull_score + (at_bottom ? 2 : 0)  // At oversold zone
bull_score := bull_score + (bullish_rejection or bullish_engulf ? 3 : 0)  // Strong price rejection
bull_score := bull_score + (bullish_div ? 3 : 0)  // Momentum divergence
bull_score := bull_score + (is_vol_spike ? 1 : 0)  // Volume climax
bull_score := bull_score + (rsi < 30 ? 1 : 0)  // RSI oversold

// Net Signal (-10 to +10)
reversal_signal = bull_score - bear_score

// ==========================================
// 7. VISUALIZATION
// ==========================================

// A. Main Oscillator: Reversal Signal
plot(reversal_signal, "Reversal Signal", color=reversal_signal > 0 ? color.green : color.red, style=plot.style_columns, linewidth=3)

// B. Reference Lines
hline(5, "Strong Bull", color=color.green, linestyle=hline.style_dashed)
hline(-5, "Strong Bear", color=color.red, linestyle=hline.style_dashed)
hline(0, "Neutral", color=color.gray)

// C. RSI Subplot (for visual divergence confirmation)
plot(rsi - 50, "RSI (Centered)", color=color.new(color.blue, 50), linewidth=1)

// D. Volume Pressure Indicator
vol_pressure = (volume / vol_ma - 1) * 10  // Normalized volume deviation
plot(vol_pressure, "Volume Pressure", color=color.new(color.orange, 70), style=plot.style_area)

// E. Signal Markers
strong_bull_reversal = bull_score >= 7
strong_bear_reversal = bear_score >= 7

plotshape(strong_bull_reversal, "Strong Bullish Reversal", shape.triangleup, location.bottom, color.lime, size=size.normal, text="REV")
plotshape(strong_bear_reversal, "Strong Bearish Reversal", shape.triangledown, location.top, color.red, size=size.normal, text="REV")

// ==========================================
// 8. ALERTS
// ==========================================
alertcondition(strong_bull_reversal, "Bullish Reversal Confirmed", "15m BULLISH REVERSAL: Momentum+Price+Volume Confluence Detected")
alertcondition(strong_bear_reversal, "Bearish Reversal Confirmed", "15m BEARISH REVERSAL: Momentum+Price+Volume Confluence Detected")

// ==========================================
// 9. TABLE: Real-Time Score Breakdown
// ==========================================
var table score_table = table.new(position.top_right, 2, 6, bgcolor=color.new(color.black, 80), border_width=1)

if barstate.islast
    table.cell(score_table, 0, 0, "Factor", text_color=color.white, text_size=size.small)
    table.cell(score_table, 1, 0, "Status", text_color=color.white, text_size=size.small)
    
    table.cell(score_table, 0, 1, "Price Extreme", text_color=color.gray, text_size=size.tiny)
    table.cell(score_table, 1, 1, at_top ? "Top" : at_bottom ? "Bottom" : "Mid", text_color=at_top ? color.red : at_bottom ? color.green : color.gray, text_size=size.tiny)
    
    table.cell(score_table, 0, 2, "Divergence", text_color=color.gray, text_size=size.tiny)
    table.cell(score_table, 1, 2, bearish_div ? "Bear" : bullish_div ? "Bull" : "None", text_color=bearish_div ? color.red : bullish_div ? color.green : color.gray, text_size=size.tiny)
    
    table.cell(score_table, 0, 3, "Rejection", text_color=color.gray, text_size=size.tiny)
    table.cell(score_table, 1, 3, bearish_rejection or bearish_engulf ? "Bear" : bullish_rejection or bullish_engulf ? "Bull" : "None", text_color=bearish_rejection or bearish_engulf ? color.red : bullish_rejection or bullish_engulf ? color.green : color.gray, text_size=size.tiny)
    
    table.cell(score_table, 0, 4, "Volume", text_color=color.gray, text_size=size.tiny)
    table.cell(score_table, 1, 4, is_vol_spike ? "Climax" : is_vol_dry ? "Dry" : "Normal", text_color=is_vol_spike ? color.orange : color.gray, text_size=size.tiny)
    
    table.cell(score_table, 0, 5, "Signal", text_color=color.white, text_size=size.small)
    table.cell(score_table, 1, 5, str.tostring(reversal_signal), text_color=reversal_signal > 5 ? color.lime : reversal_signal < -5 ? color.red : color.gray, text_size=size.small)

Overview

15m Reversal Detector uses RSI, MACD and a stochastic reading for momentum, volume spikes and dry-ups against a volume average, Bollinger Band extremes, wick rejection and engulfing candles, and pivot-based divergence. Inputs set the lengths, volume multiplier, wick ratio and divergence pivot lookback. The text mentions 15-minute use, but the settings work on other timeframes. It marks setups and is not a full trading system.

Details

Published by

caizongxun on GitHub

Type

Indicator, Pine Script v5

Draws

Separate pane below the chart

Category

Oscillators & momentum, Divergence, Candlestick patterns, Volume

Markets

Crypto

Timeframes

M15-H1

Risk Notes

No repainting, lookahead or stacked entries were found in its code or README. That says nothing about how well it works: test it first.

Settings

The inputs you can change from the gear icon on the chart. Defaults are the author's.

SettingTypeDefaultVariable
RSI Lengthint14rsi_len
MACD Fastint12macd_fast
MACD Slowint26macd_slow
MACD Signalint9macd_sig
Volume MA Lengthint20vol_ma_len
Volume Spike Multiplierfloat2.0vol_spike_mult
Min Wick/Body Ratio for Rejectionfloat0.6wick_ratio
BB Length (for Extreme Detection)int20bb_len
BB Multfloat2.0bb_mult
Pivot Lookback for Divergenceint5lookback_div
Third-party code. ForexR did not write, test or endorse this script, and the summary above was generated automatically from its code and README. Indicators describe the past, and a strategy's backtest can look better than live trading, especially when a script repaints. Check it in the Strategy Tester and on a demo account before you rely on it.

Similar Pine Scripts

Commitment Gauge

by harryguiacorn
219 stars

This indicator measures directional momentum by evaluating candlestick body proportions and volume over a user-defined lookback window. It computes the ratio of candle body to total range, weights the cumulative value by volume and absolute body size, and dete

Indicator v4 VolumeCandlestick patterns
Updated 1 year ago · None stated GitHub repository of Commitment Gauge

Oscillator Suite

by TamaraKGreen
46 stars

Oscillator Suite plots a normalised price oscillator in a separate pane and overlays a signal line that can use SMA, EMA, WMA, HMA, RMA, VWMA, T3, ZEMA, KAMA, or GKEMA. It marks bullish and bearish divergences, a smoothed money-flow series, confluence areas an

Indicator v5 Oscillators & momentumDivergence
Updated 7 weeks ago · None stated GitHub repository of Oscillator Suite

MFI Divergences

by tistaharahap
25 stars

This indicator plots the Money Flow Index in a separate pane and marks regular and hidden bullish and bearish divergences between price pivots and the oscillator. It builds the index from positive and negative money flow, then finds pivot highs and lows using

Indicator v4 Oscillators & momentumVolume
Updated 6 years ago · None stated GitHub repository of MFI Divergences
24 stars

This indicator plots a Cipher B-style oscillator in a separate pane and can source its calculations from Heikin Ashi candles when that option is on. It draws WaveTrend lines with optional buy, gold, sell, and divergence dots, plus overbought and oversold level

Indicator v5 Oscillators & momentumDivergence
Updated 4 years ago · MPL-2.0 GitHub repository of Cipher B Heikin Ashi
11 stars

This indicator plots a smoothed Z-score of cumulative volume delta in a separate pane, showing whether buying or selling pressure is dominant and when the reading enters extreme zones. It marks spot accumulation, climax or exhaustion, and pivot-based price-vol

Indicator v6 Oscillators & momentumVolume Repaints
Updated 7 weeks ago · MIT GitHub repository of CVD Z-Score [NeuNue]

The Candle Pressure Index measures buying versus selling pressure from candle geometry and relative volume. Each bar combines close location, body ratio, and volume rank into a raw pressure value. An exponential moving average of that pressure forms the CPI os

Indicator v6 Oscillators & momentumVolume
Updated 2 days ago · MIT GitHub repository of Candle Pressure Index [WavesUnchained]

More indicators

Trade Your Charts With a Regulated Broker

Compare brokers that connect to TradingView, with spreads, minimum deposits and leverage side by side.

Compare brokers