Mean Deviation Trend [BackQuant]Mean Deviation Trend
Overview
Mean Deviation Trend is a structure-based trend and regime indicator that measures directional pressure as the market’s sustained deviation from a moving “mean,” then uses that pressure to drive an adaptive band , dynamic coloring, and a level engine that marks deviation peak extremes after momentum fades.
Most trend tools start with direction, for example slope or MA cross, then try to estimate strength later. This script does the reverse:
It first quantifies how far price is displaced from a central mean in volatility-adjusted units .
It then smooths and accumulates that deviation to determine trend direction and conviction .
Finally it converts conviction into a band that tightens when pressure is strong and widens when pressure is weak.
The result is a single framework that blends:
A mean anchor (EMA).
A signed deviation engine normalized by ATR.
A conviction score based on sustained deviation.
An adaptive band that behaves like dynamic support/resistance.
A “deviation peak” level system that plants levels at extremes after the push fades.
Optional glow, fills, candle coloring, and flip markers.
Core concept: deviation from mean as trend fuel
A trend is not just “price up” or “price down.” A trend is a persistent imbalance where price spends time displaced from fair value and keeps re-asserting that displacement. This indicator treats the mean as a moving fair value proxy, and it measures how aggressively price is departing from it.
Key idea:
If price stays above the mean and that displacement is sustained, bullish pressure is dominant.
If price stays below the mean and that displacement is sustained, bearish pressure is dominant.
If price keeps snapping back and deviation cannot sustain, regime is weak and uncertainty is high.
This is why the script doesn’t rely on a single moment like a cross. It cares about persistence .
Mean anchor (the “center of gravity”)
The mean is defined as an EMA of close:
mean = EMA(close, meanLen)
Why EMA:
It responds faster than SMA to regime changes.
It provides a stable anchor without overreacting to single bars.
The mean line is not just a moving average here, it is the reference line that deviation is measured against. Everything downstream depends on the mean being a consistent “center.”
Volatility normalization (why ATR is essential here)
Raw distance from mean is meaningless across volatility regimes. A $200 deviation on BTC might be noise one week and huge another week. To fix this, the script normalizes deviation by ATR:
atr = ATR(14)
rawDev = (close - mean) / atr
Interpretation:
rawDev is “how many ATR units price is away from the mean.”
This makes deviation comparable across timeframes and volatility states.
This is critical because it turns the indicator into a dimensionless pressure metric rather than a price-distance tool.
Deviation smoothing (instantaneous pressure vs noisy pressure)
Instantaneous deviation can spike on one candle and mean nothing. So the script applies EMA smoothing to raw deviation:
devSmooth = EMA(rawDev, devLen)
What this does:
Reduces single-bar spikes.
Keeps the sign and general magnitude of displacement.
Creates a cleaner “pressure line” that responds but does not jitter.
This is the first stage of filtering: “Are we meaningfully deviating, or just wicking?”
Deviation accumulation (turning pressure into conviction)
This is the part that makes the indicator behave like a trend conviction model rather than a simple oscillator.
The script computes:
cumDev = SMA(devSmooth, devAccum)
Even though it’s coded as an SMA, conceptually it behaves like a rolling accumulation of the deviation signal:
If devSmooth stays positive for multiple bars, cumDev rises and stays positive.
If devSmooth stays negative for multiple bars, cumDev drops and stays negative.
If devSmooth flips sign repeatedly, cumDev compresses toward zero.
This is the key “persistence detector.” It converts short-term deviation into a medium-term conviction read.
Trend direction and flips
Trend direction is derived purely from the sign of cumulative deviation:
tDir = cumDev > 0 ? +1 : -1
flip = tDir != tDir
Interpretation:
Bull regime means the market’s sustained deviation is above the mean (pressure up).
Bear regime means sustained deviation is below the mean (pressure down).
A flip marks a regime transition where the sustained bias changes sign.
This is intentionally simple because all the complexity is in how cumDev is built.
Measuring conviction: devNorm (adaptive strength scale)
The script measures absolute conviction:
devAbs = abs(cumDev)
Then it normalizes it relative to a rolling peak:
devHigh = highest(devAbs, 80)
devNorm = devHigh > 0 ? min(devAbs / devHigh, 1) : 0
Meaning:
devNorm is a 0..1 strength scale.
0 means current conviction is tiny relative to recent extremes.
1 means conviction is at the strongest level seen in the last ~80 bars.
This is not a z-score, it’s a “relative-to-recent-peak” normalization. That matters because it makes the band behavior adapt to each instrument’s recent character, not a fixed threshold system.
Adaptive band logic (tight when confident, wide when uncertain)
The band is built to behave differently depending on conviction. When conviction is strong, the band should hug price and act like a close structural guide. When conviction is weak, the band should widen and stop pretending it is precise.
This is done by interpolating between two ATR multipliers:
bandTight = ATR multiplier when devNorm is high
bandWide = ATR multiplier when devNorm is low
bandMult = bandWide - devNorm * (bandWide - bandTight)
bandW = atr * bandMult
Interpretation:
devNorm near 1 → bandMult approaches bandTight → band width shrinks.
devNorm near 0 → bandMult approaches bandWide → band width expands.
So the band width is not arbitrary. It is a direct function of trend conviction.
Active band placement (trend-aware support/resistance)
The “active band” is placed on the opposite side of the mean depending on direction:
If bullish: activeBand = mean - bandW
If bearish: activeBand = mean + bandW
So in bullish regimes, the band behaves like a dynamic support zone beneath the mean. In bearish regimes, it behaves like dynamic resistance above the mean.
Then it is smoothed:
activeBand = EMA(activeBand, 3)
This prevents the band from stepping too harshly when ATR shifts.
Outer band (secondary structure reference)
A second band is created at half width on the opposite side:
bull: outerBand = mean + bandW * 0.5
bear: outerBand = mean - bandW * 0.5
Then smoothed again. This outer line is not the main “stop band,” it is more of an additional structure marker to show where the mean plus/minus partial deviation zone sits. It can help visually gauge whether price is extended relative to the mean structure while still in the same regime.
Color system (strength-aware gradient)
The trend color is not binary. It is strength-weighted:
If bullish, devNorm drives a gradient from a faint bull tint to full bull.
If bearish, devNorm drives a gradient from a faint bear tint to full bear.
This gives you an immediate read:
Bright strong color = conviction high.
Faded color = conviction low, regime fragile.
It also ties into the glow and fill so the whole visual language matches the same underlying “pressure” variable.
Deviation peak level engine (how the script plants levels)
This indicator includes a separate mechanism that marks important extremes after a strong deviation push fades. The idea is:
When trend pressure peaks and then collapses, the extreme price printed at peak deviation often becomes a reaction level later.
This is similar in spirit to:
exhaustion extremes,
climactic deviation points,
distribution/accumulation turning zones,
but the script formalizes it using the deviation engine.
1) Track the strongest deviation peak
The script stores a running peak:
peakDev: maximum devAbs seen since last reset
peakPrice: the extreme price at that peak (high for bull, low for bear)
peakDir: direction at peak
peakBar: bar index of peak
When devAbs prints a new high, it updates those values.
2) Define “fade” (momentum has cooled)
A fade event triggers when:
peakDev is meaningfully large (peakDev > 0.3)
current devAbs drops below a fraction of the peak: devAbs < peakDev * fadeThr
fadeThr is the key user control. Lower fadeThr requires a deeper drop from peak before planting a level.
What “fade” means in practice:
A strong push happened (deviation expanded).
That push is no longer active (deviation contracted).
So the extreme created during the push is now “locked in” as a candidate level.
3) Plant a level at the extreme
When faded:
A dashed horizontal line is created at peakPrice.
The line is projected forward (bar_index + 60).
It is stored in an array with direction and retest state.
It also respects maxLvls by deleting the oldest levels to avoid clutter.
4) Maintain levels and delete invalid ones
Each bar, levels are checked:
If price breaks far beyond the level (by about 2 ATR in the wrong direction), the level is deleted.
That “broken” rule is a pragmatic invalidation filter. If price rips through a former deviation extreme by a large margin, the level is no longer acting like a meaningful reaction zone.
5) Detect retests and mark them
A retest is detected when:
close is within ~0.25 ATR of the level,
and two bars ago price was not near it (distance > 0.5 ATR),
and the level hasn’t already been marked as retested.
When that happens:
A diamond marker is printed (◆) above or below depending on approach.
The level is flagged as retested so it won’t spam markers.
So levels are not just static drawings. They have state: naked vs retested, and they get culled if invalidated.
Glow system (volatility-scaled aesthetic, strength-scaled intensity)
Glow is not random decoration here. Its width scales with devNorm:
glowMult = 0.4 + devNorm * 1.2
glowW = atr * 0.08 * glowMult
So in strong trends:
Glow band expands.
The mean core visually “radiates” more.
In weak trends:
Glow shrinks and becomes less prominent.
The glow is built using multiple invisible plots above and below the mean, then layered fills with different transparencies. It creates a soft gradient aura around the mean that encodes strength.
Band fill and line break behavior
The active band is plotted with plot.style_linebr and forced to break on flips:
bandBrk = flip ? na : activeBand
This prevents the band from drawing a misleading connecting line across a regime change. It visually resets when direction flips, which matters because the band swaps sides of the mean when regime changes.
Fill is drawn between:
the active band line
and hl2 (mid-price reference)
So you get a shaded zone that reflects the current regime color and strength.
Candles and flip labels
Candles can be colored by the same strength-weighted regime color, which makes the entire chart consistent.
On flips:
Bull flip prints ▲ at the low.
Bear flip prints ▼ at the high.
These are regime markers, not “entry signals” by default. They simply identify when the cumulative deviation sign changed.
How to read this indicator in practice
1) Regime and conviction
Direction comes from cumDev sign.
Conviction comes from devNorm intensity.
Bright color + stable band on one side means strong sustained pressure.
Faded color + widening band means weak sustained pressure and higher uncertainty.
2) Using the active band as structure
In a bullish regime, activeBand is below mean and can behave like:
dynamic support,
risk boundary,
trend “line in the sand.”
In bearish regime, it flips above mean and acts like dynamic resistance.
Because the band widens when conviction is low, it naturally tells you “do not treat this as a tight stop zone when the trend is weak.”
3) Using deviation peak levels
Peak levels represent exhaustion extremes after a strong deviation impulse faded:
If price returns to a naked level, that area can act as a reaction zone.
Once retested, the script marks it and treats it as less “special.”
If price breaks it by a wide margin, the script removes it as invalid.
This level engine is best viewed as “structural memory of deviation events,” not generic support/resistance.
4) Extreme deviation alert
devNorm > 0.85 means the current sustained deviation is near the strongest seen recently. That’s useful for:
identifying trend climax states,
detecting when continuation is strong but risk of snapback rises,
flagging conditions where mean reversion pressure is building.
It does not guarantee reversal, it flags “stretch.”
Inputs and what they actually change
Mean Length (meanLen)
Controls the anchor responsiveness:
Lower = mean follows price more closely, deviation shrinks, more frequent flips.
Higher = mean is slower, deviation grows, trend regimes last longer.
Deviation Smoothing (devLen)
Controls how noisy the deviation signal is:
Lower = faster response, more jitter.
Higher = smoother pressure, slower flips.
Deviation Accumulation (devAccum)
Controls persistence requirement:
Lower = trend conviction reacts quickly but can whipsaw.
Higher = requires sustained deviation, fewer flips, more confirmation.
Band Tight / Band Wide
These define the band behavior range:
bandTight: how close the band gets when conviction is strong.
bandWide: how far it drifts when conviction is weak.
If you want the band to behave more like a stop guide, reduce bandWide. If you want it to act more like a regime boundary, increase bandWide.
Fade Threshold + Max Levels
These shape the level engine:
fadeThr lower = requires bigger cooling before planting levels (fewer, more meaningful).
fadeThr higher = plants levels earlier (more levels, more noise).
maxLvls controls clutter and historical depth.
Alerts (what they represent)
Dev Bull / Dev Bear: regime flips, cumulative deviation changed sign.
Dev Faded: a deviation peak cooled enough to plant a level.
Extreme Dev: sustained deviation is near local maximum, stretch condition.
Summary
Mean Deviation Trend models trend as sustained, volatility-normalized displacement from a mean rather than simple direction. It smooths and accumulates signed deviation to extract regime and conviction, then converts that conviction into an adaptive ATR band that tightens when pressure is strong and widens when pressure is weak. On top of that, it tracks deviation peak extremes and plants forward levels only after deviation fades, creating a structured map of “where trend impulses peaked” and how price reacts when those zones are revisited.
Penunjuk Pine Script®






















