The Moving Average Trend Sniper indicator is designed to detect trend movements more accurately than traditional moving averages. This indicator goes beyond simple price averaging: it integrates adaptive volatility-based smoothing, dynamic trend filters, and slope analysis to deliver a clearer picture of market direction.
Its main goal is to provide a smart and visual trend-following tool, highly responsive to significant price shifts while filtering out noise during sideways markets.
This indicator is built upon a solid base of advanced technical analysis concepts. Its core logic combines:
Here’s a breakdown of the indicator’s main components:
This smoothing mechanism adapts only when structural changes are detected in recent highs or lows. If not enough bars are available, it falls back to using the close price.
The indicator calculates a slope normalized by ATR and converts it into an angle. Based on the angle’s sign, it chooses the data source: average of highs or lows.
A progressively accumulated ATR (atrema) is used to stabilize volatility calculations over time. This value is key to defining the filter’s offset and band width.
This is the core of the trend detection logic. The filter updates conditionally depending on whether the movement is strong enough. It doesn’t blindly follow price – it demands confirmation.
Plotted above and below the MATS line, these bands are based on ATR and help to visually capture zones of potential support and resistance within trends.
The indicator changes color depending on whether price is above or below the trend filter, giving a quick visual cue of the prevailing trend direction.
The indicator includes several tunable parameters for greater flexibility:
length (default: 30): main smoothing period. Higher values slow the indicator down.atrMult (default: 0.5): ATR multiplier for the envelope bands. Higher values create wider bands.wildersPeriod and atrPeriod: automatically calculated from length.Tip: for highly volatile instruments or lower timeframes, consider using a smaller length (10–20). For daily or weekly charts, keeping it at 30 or even higher is more effective for capturing long-term trends.
This indicator is especially useful for:
Compared to a classic moving average (like EMA or SMA), the Trend Sniper adapts its behavior to market conditions, providing better-informed signals and reducing lag in evolving markets.
//-----------------------------------------//
//PRC_Moving Avg Trend Sniper
//version = 0
//19.05.2025
//Iván González @ www.prorealcode.com
//Sharing ProRealTime knowledge
//-----------------------------------------//
// === PARAMETERS ===
//-----------------------------------------//
length = 30 // main smoothing length
wildersPeriod = length * 4 - 1
atrPeriod = length
atrMult = 0.5 // multiplier for upper/lower ATR band
//-----------------------------------------//
// === CUSTOM EMA FUNCTION ===
//-----------------------------------------//
ONCE atrema = 0
ONCE count = 0
IF barindex <= 1 THEN
atrema = 0
count = 0
ELSE
count = count + 1
atrema = (1 - 2 / (count + 1)) * atrema + 2 / (count + 1) * tr
ENDIF
//-----------------------------------------//
// === TRA() FUNCTION ===
//-----------------------------------------//
atrLocal = atrema
slope = (close - close[10]) / (atrLocal * 10)
angle = ATAN(slope)
IF angle > 0 THEN
source = average[2](high)
ELSE
source = average[2](low)
ENDIF
//-----------------------------------------//
// === CHEBYSHEV-LIKE ADAPTIVE SMOOTHING ===
//-----------------------------------------//
// Applies smoothing only when barindex is sufficient
IF barindex <= length THEN
smooth = close
ELSE
highChange = (HIGHEST[length](high) - HIGHEST[length+1](high)) <> 0
lowChange = (LOWEST[length+1](low) - LOWEST[length](low)) <> 0
boolImpulse = highChange OR lowChange
timeConstant = POW(AVERAGE[length](boolImpulse), 2)
smooth = smooth + timeConstant * (source - smooth)
ENDIF
//-----------------------------------------//
// === MODIFIED ATR CALCULATION ===
//-----------------------------------------//
atr = ABS(smooth[1] - smooth)
maAtr = average[wildersPeriod,1](atr)
deltaATR = average[wildersPeriod](maAtr) * length * 0.4
//-----------------------------------------//
// === MATS CALCULATION ===
//-----------------------------------------//
// Adaptive moving average trend filter with direction-sensitive filtering
ONCE mats = smooth
IF smooth > mats[1] THEN
IF smooth - deltaATR < mats[1] THEN
mats = mats[1]
ELSE
mats = smooth - deltaATR
ENDIF
ELSE
IF smooth + deltaATR > mats[1] THEN
mats = mats[1]
ELSE
mats = smooth + deltaATR
ENDIF
ENDIF
//-----------------------------------------//
// === ATR-BASED ENVELOPE BANDS ===
//-----------------------------------------//
atr10 = atrema / 2
maxBand = mats + atr10 * atrMult
minBand = mats - atr10 * atrMult
//-----------------------------------------//
// === DYNAMIC COLORING BASED ON TREND DIRECTION ===
//-----------------------------------------//
IF AVERAGE[2](close) > mats THEN
r = 0
g = 0
b = 255
ELSE
r = 255
g = 175
b = 100
ENDIF
// Shaded background between bands
colorbetween(maxBand, minBand, r, g, b, 30)
//-----------------------------------------//
RETURN mats COLOURED(r, g, b) STYLE(line, 3)