The standard Parabolic SAR has one well-known limitation: its acceleration factor increments at a fixed rate regardless of what the market is actually doing. A quiet consolidation bar and a strong breakout bar both push the SAR by the same step. HiperSAR addresses this by replacing the fixed step with a dynamic coefficient that responds to two things at once, how volatile the current bar is relative to recent average range, and how much directional conviction that bar carries.
The volatility part works by comparing the current bar’s High-Low range to a short-term ATR baseline. When the market expands and price moves with force, the SAR accelerates faster and stays closer to price. When the market contracts and ranges compress, it eases off and gives the trade more room.
The conviction part is the additional refinement introduced in this ProRealTime version. A wide bar that closes near its extreme (a strong bull or bear candle) scores high on directional conviction and gets the full acceleration. A wide bar with a tiny body, like a doji or a spike with long wicks, scores low and gets a dampened acceleration even if the raw range was large. This distinction matters because the original High-Low ratio alone cannot tell the difference between a volatile trending bar and a volatile indecisive one.
The two components are blended together into a single AF value that is then clamped between 0.01 and 0.25, keeping it within the same practical bounds as a classical Parabolic SAR while making it significantly more market-aware.
The indicator plots as two separate dot series directly on the price chart, green dots below price during uptrends and red dots above price during downtrends. A dot switching sides signals a potential trend reversal, same reading as the standard SAR but with entries and exits that are timed more closely to actual momentum shifts.
Works well as a trailing stop reference on trending instruments. Because the AF is tied to momentum and conviction rather than a fixed schedule, it tends to stay closer to price during strong moves and give more slack during choppy or ranging conditions. As with any SAR-based tool, it is best used in combination with a trend filter to avoid frequent whipsaws in sideways markets.
// -------------------------------------------------------
// PRC_HiperSAR - ProRealTime / ProBuilder version
// Original idea by Garry119, MQ4 code by Genry(gm)
// ProRealTime port + directional AF enhancement by ProRealCode
// www.prorealcode.com
// -------------------------------------------------------
// The core concept: replace the fixed Parabolic SAR acceleration
// factor with a dynamic coefficient driven by the bar's HL range
// relative to a short-term average range (ATR-based normalization).
//
// Enhancement added here: the AF is also weighted by the bar's
// directional conviction, measured as body size relative to total
// range. A strong trending bar (large body, small wicks) gets a
// higher AF than a wide doji (large range but no body).
// This makes the SAR accelerate faster on genuine momentum bars
// and stay cautious on indecisive or volatile-but-directionless bars.
// -------------------------------------------------------
// --- Parameters ---
Mult = 1.0 // Multiplier for the range-based AF
atrPeriod = 10 // Lookback for average range normalization
// -------------------------------------------------------
// Step 1: compute the dynamic acceleration factor
// -------------------------------------------------------
if barindex>atrPeriod then
// Current bar range and ATR-based average range
currentRange = HIGH - LOW
avgRange = AVERAGETRUERANGE[atrPeriod](CLOSE)
// Protect against zero or near-zero average range
IF avgRange < 0.000001 THEN
avgRange = 0.000001
ENDIF
IF currentRange < 0.000001 THEN
currentRange = 0.000001
ENDIF
// Raw volatility ratio (linear, matching original MQ4 logic)
ratio = currentRange / avgRange
// Directional conviction weight:
// body = absolute distance between open and close
// A body close to the total range means a strong directional bar.
// A tiny body means a doji or inside bar, low conviction.
// convictionWeight ranges from 0 (pure doji) to 1 (full-body bar).
body = ABS(CLOSE - OPEN)
IF currentRange > 0.000001 THEN
convictionWeight = body / currentRange
ELSE
convictionWeight = 0
ENDIF
// Blend the raw volatility ratio with the conviction weight.
// Without conviction weighting, a spike bar and a trend bar with
// the same HL range would produce the same AF, even though the
// spike offers no directional signal.
// The blend formula: we scale the ratio by a factor that sits
// between a minimum floor (0.5, so even doji bars contribute
// some acceleration) and 1.0 for fully convicted bars.
convictionFactor = 0.5 + 0.5 * convictionWeight
// Directionally-aware dynamic AF
k = 0.02 + (ratio * convictionFactor * Mult * 0.03)
// Clamp to reasonable bounds (same as original)
k = MAX(0.01, MIN(0.25, k))
// -------------------------------------------------------
// Step 2: SAR recursive logic
// Carries sar, ep and trend forward bar by bar using
// ProRealTime's native series memory (variable[1] lookback)
// -------------------------------------------------------
// Read previous bar state
prevTrend = trend[1]
prevEP = ep[1]
// Recover previous SAR value from whichever buffer was active
IF prevTrend = 1 THEN
prevSAR = sarUp[1]
ELSE
prevSAR = sarDn[1]
ENDIF
// On the very first bar, bootstrap the state from bar direction
IF BARINDEX = 0 THEN
IF CLOSE > OPEN THEN
trend = 1
ep = HIGH
sarUp = LOW
sarDn = 0
ELSE
trend = -1
ep = LOW
sarUp = 0
sarDn = HIGH
ENDIF
ELSE
newTrend = prevTrend
IF prevTrend = 1 THEN
// Uptrend: SAR moves up toward EP
newSAR = prevSAR + k * (prevEP - prevSAR)
// SAR cannot be above the previous bar's low (standard SAR rule)
IF newSAR > LOW[1] THEN
newSAR = LOW[1]
ENDIF
// Update extreme point if new high made
IF HIGH > prevEP THEN
newEP = HIGH
ELSE
newEP = prevEP
ENDIF
// Reversal check
IF LOW <= newSAR THEN
newTrend = -1
newEP = LOW
newSAR = HIGH
ENDIF
ELSE
// Downtrend: SAR moves down toward EP
newSAR = prevSAR - k * (prevSAR - prevEP)
// SAR cannot be below the previous bar's high
IF newSAR < HIGH[1] THEN
newSAR = HIGH[1]
ENDIF
// Update extreme point if new low made
IF LOW < prevEP THEN
newEP = LOW
ELSE
newEP = prevEP
ENDIF
// Reversal check
IF HIGH >= newSAR THEN
newTrend = 1
newEP = HIGH
newSAR = LOW
ENDIF
ENDIF
trend = newTrend
ep = newEP
IF newTrend = 1 THEN
sarUp = newSAR
sarDn = 0
ELSE
sarDn = newSAR
sarUp = 0
ENDIF
ENDIF
plotUp = sarUp
plotDn = sarDn
endif
RETURN plotUp COLOURED(0, 200, 0) STYLE(POINT, 3) AS "HiperSAR Bull", plotDn COLOURED(220, 0, 0) STYLE(POINT, 3) AS "HiperSAR Bear"