
Identifies high-probability bullish and bearish reversal zones by combining four confluence signals — candlestick patterns, support/resistance levels, RSI divergence, and volume confirmation. Signals are rated ★ to ★★★ based on how many confluences align. Only trade ★★★ signals.
Use this indicator after the Simple Screener narrows your watchlist
Critical rule: Never enter on the signal candle itself. Always wait for the next candle to close above the signal candle high (bullish) or below the signal candle low (bearish). This confirmation step eliminates the majority of false signals.
More confluences = higher probability — only trade ★★★
Click each signal to see all patterns and the logic behind them
Including alert setup — takes about 10 minutes
The script includes four built-in alert conditions. Set these up on your watchlist stocks and TradingView will notify you on your phone the moment a high-probability reversal fires.
Alert setup: Right-click indicator on chart → Add Alert → select condition → set "Once Per Bar Close" → enable mobile push notifications.
This indicator identifies potential reversals — not guaranteed ones. All signals require confirmation from the next candle before entering.
In strong trending markets, reversal signals can fail repeatedly. Always check the broader market verdict (from your Sunday Review) before acting on any signal.
Do not use this indicator as your only reason to enter a trade. It is one tool in the workflow — combine it with the Simple Screener score and the Position Size Calculator.
Copy and paste into TradingView Pine Editor
// Jessie's Market Reversal Screener
// Culgan Wealth | Pine Script v6
// Four confluence signals: Candlestick Pattern + S/R Level + RSI Divergence + Volume
// Signal Strength: 3=HIGH 2=MED 1=LOW
// HOW TO USE: Daily chart, look for 3-HIGH signals at key S/R levels
// Wait for NEXT candle to confirm before entering. Stop below signal low (bull) or above signal high (bear).
//@version=6
indicator("Jessie's Market Reversal Screener", shorttitle="Jessie Reversal", overlay=true, max_bars_back=500)
// INPUTS
bodyRatio = input.float(0.6, "Min Body Ratio (Engulfing)", group="Candles", minval=0.1, maxval=1.0, step=0.05)
dojiRatio = input.float(0.15, "Max Body Ratio (Doji)", group="Candles", minval=0.01, maxval=0.5, step=0.01)
hammerRatio = input.float(0.35, "Max Body Ratio (Hammer)", group="Candles", minval=0.1, maxval=0.6, step=0.05)
rsiLen = input.int(14, "RSI Length", group="RSI", minval=2)
rsiOB = input.float(70, "RSI Overbought", group="RSI", minval=50, maxval=90)
rsiOS = input.float(30, "RSI Oversold", group="RSI", minval=10, maxval=50)
divLookback = input.int(14, "Divergence Lookback", group="RSI", minval=5, maxval=50)
swingLen = input.int(10, "Swing Lookback", group="S/R", minval=3)
srZonePct = input.float(0.5, "S/R Zone Tolerance %", group="S/R", minval=0.1, maxval=2.0, step=0.1)
volMaLen = input.int(20, "Volume MA Length", group="Volume", minval=5)
volMultiplier = input.float(1.0, "Volume Multiplier", group="Volume", minval=0.5, maxval=3.0, step=0.1)
minStrength = input.int(2, "Min Signal Strength (1-3)", group="Display", minval=1, maxval=3)
// COLOURS
C_CYAN = color.rgb(0, 212, 170)
C_RED = color.rgb(239, 68, 68)
C_NAVY = color.rgb(13, 20, 33)
C_SLATE = color.rgb(148, 163, 184)
C_LIGHT = color.rgb(203, 213, 225)
C_BORDER = color.rgb(30, 58, 95)
// CANDLE MATHS
candleRange = high - low
candleBody = math.abs(close - open)
upperWick = high - math.max(close, open)
lowerWick = math.min(close, open) - low
isBull = close > open
isBear = close < open
bodyPct = candleRange > 0 ? candleBody / candleRange : 0
rsiVal = ta.rsi(close, rsiLen)
volMa = ta.sma(volume, volMaLen)
volOk = volume >= volMa * volMultiplier
ema21 = ta.ema(close, 21)
downtrend = close < ema21
uptrend = close > ema21
// CANDLESTICK PATTERNS
bullEngulf = isBear[1] and isBull and close > open[1] and open < close[1] and bodyPct >= bodyRatio
bearEngulf = isBull[1] and isBear and close < open[1] and open > close[1] and bodyPct >= bodyRatio
hammer = downtrend and bodyPct <= hammerRatio and lowerWick >= candleBody * 2.0 and upperWick <= candleBody * 0.5
shootingStar = uptrend and bodyPct <= hammerRatio and upperWick >= candleBody * 2.0 and lowerWick <= candleBody * 0.5
doji = bodyPct <= dojiRatio
bullDoji = doji and downtrend and rsiVal < rsiOS + 15
bearDoji = doji and uptrend and rsiVal > rsiOB - 15
morningStar = isBear[2] and candleBody[2] / candleRange[2] >= 0.5 and candleBody[1] / candleRange[1] <= 0.35 and isBull and candleBody / candleRange >= 0.5 and close > (open[2] + close[2]) / 2
eveningStar = isBull[2] and candleBody[2] / candleRange[2] >= 0.5 and candleBody[1] / candleRange[1] <= 0.35 and isBear and candleBody / candleRange >= 0.5 and close < (open[2] + close[2]) / 2
bullCandle = bullEngulf or hammer or bullDoji or morningStar
bearCandle = bearEngulf or shootingStar or bearDoji or eveningStar
// SUPPORT AND RESISTANCE
pivotH = ta.pivothigh(high, swingLen, swingLen)
pivotL = ta.pivotlow(low, swingLen, swingLen)
var float lastPH = na
var float lastPL = na
if not na(pivotH)
lastPH := pivotH
if not na(pivotL)
lastPL := pivotL
tol = close * (srZonePct / 100)
nearSup = not na(lastPL) and math.abs(close - lastPL) <= tol
nearRes = not na(lastPH) and math.abs(close - lastPH) <= tol
prevDH = request.security(syminfo.tickerid, "D", high[1])
prevDL = request.security(syminfo.tickerid, "D", low[1])
nearPrevH = math.abs(close - prevDH) <= tol
nearPrevL = math.abs(close - prevDL) <= tol
bullSR = nearSup or nearPrevL
bearSR = nearRes or nearPrevH
// RSI DIVERGENCE
lowestLow = ta.lowest(low, divLookback)
highestHigh = ta.highest(high, divLookback)
lowestRsi = ta.lowest(rsiVal, divLookback)
highestRsi = ta.highest(rsiVal, divLookback)
bullDiv = low <= lowestLow and rsiVal > lowestRsi and rsiVal < rsiOS + 20
bearDiv = high >= highestHigh and rsiVal < highestRsi and rsiVal > rsiOB - 20
// SIGNAL STRENGTH
bullCount = (bullCandle ? 1 : 0) + (bullSR ? 1 : 0) + (bullDiv ? 1 : 0) + (volOk ? 1 : 0)
bearCount = (bearCandle ? 1 : 0) + (bearSR ? 1 : 0) + (bearDiv ? 1 : 0) + (volOk ? 1 : 0)
bullStr = math.min(bullCount, 3)
bearStr = math.min(bearCount, 3)
bullSig = bullCandle and bullStr >= minStrength
bearSig = bearCandle and bearStr >= minStrength
// BACKGROUND HIGHLIGHT for 3-star signals
bgcolor(bullSig and bullStr >= 3 ? color.new(C_CYAN, 93) : bearSig and bearStr >= 3 ? color.new(C_RED, 93) : na, title="Reversal Zone")
// PLOTS
plot(bullStr > 0 ? bullStr : na, "Bull Strength", C_CYAN, display=display.none)
plot(bearStr > 0 ? bearStr : na, "Bear Strength", C_RED, display=display.none)
plot(rsiVal, "RSI", C_SLATE, display=display.none)
// ALERTS
alertcondition(bullSig and bullStr >= 3, title="Jessie Reversal - Strong Bullish", message="{{ticker}} - Strong Bullish Reversal 3-star | Price: {{close}}")
alertcondition(bullSig and bullStr >= 2, title="Jessie Reversal - Bullish Signal", message="{{ticker}} - Bullish Reversal 2-star | Price: {{close}}")
alertcondition(bearSig and bearStr >= 3, title="Jessie Reversal - Strong Bearish", message="{{ticker}} - Strong Bearish Reversal 3-star | Price: {{close}}")
alertcondition(bearSig and bearStr >= 2, title="Jessie Reversal - Bearish Signal", message="{{ticker}} - Bearish Reversal 2-star | Price: {{close}}")
// INFO TABLE
var table t = table.new(position.bottom_right, 2, 6, bgcolor=color.new(C_NAVY, 10), border_color=color.new(C_BORDER, 80), border_width=1, frame_color=color.new(C_CYAN, 60), frame_width=1)
if barstate.islast
table.cell(t, 0, 0, "Jessie's Market Reversal", text_color=C_CYAN, text_size=size.small, bgcolor=C_NAVY, text_halign=text.align_left)
table.cell(t, 1, 0, "Culgan Wealth", text_color=C_SLATE, text_size=size.tiny, bgcolor=C_NAVY, text_halign=text.align_right)
table.cell(t, 0, 1, "RSI", text_color=C_LIGHT, text_size=size.tiny, bgcolor=C_NAVY, text_halign=text.align_left)
table.cell(t, 1, 1, str.tostring(math.round(rsiVal, 1)), text_color=rsiVal < rsiOS ? C_CYAN : rsiVal > rsiOB ? C_RED : C_SLATE, text_size=size.tiny, bgcolor=C_NAVY, text_halign=text.align_center)
table.cell(t, 0, 2, "Near Support", text_color=C_LIGHT, text_size=size.tiny, bgcolor=C_NAVY, text_halign=text.align_left)
table.cell(t, 1, 2, nearSup ? "YES" : "NO", text_color=nearSup ? C_CYAN : C_SLATE, text_size=size.tiny, bgcolor=C_NAVY, text_halign=text.align_center)
table.cell(t, 0, 3, "Near Resistance", text_color=C_LIGHT, text_size=size.tiny, bgcolor=C_NAVY, text_halign=text.align_left)
table.cell(t, 1, 3, nearRes ? "YES" : "NO", text_color=nearRes ? C_RED : C_SLATE, text_size=size.tiny, bgcolor=C_NAVY, text_halign=text.align_center)
table.cell(t, 0, 4, "Bull Signal", text_color=C_LIGHT, text_size=size.tiny, bgcolor=C_NAVY, text_halign=text.align_left)
table.cell(t, 1, 4, bullSig ? bullStr >= 3 ? "3 - HIGH" : "2 - MED" : "-", text_color=bullSig ? C_CYAN : C_SLATE, text_size=size.tiny, bgcolor=C_NAVY, text_halign=text.align_center)
table.cell(t, 0, 5, "Bear Signal", text_color=C_LIGHT, text_size=size.tiny, bgcolor=C_NAVY, text_halign=text.align_left)
table.cell(t, 1, 5, bearSig ? bearStr >= 3 ? "3 - HIGH" : "2 - MED" : "-", text_color=bearSig ? C_RED : C_SLATE, text_size=size.tiny, bgcolor=C_NAVY, text_halign=text.align_center)