Indicator · Pine Script v6 · On the chart

TwinSmooth ATR Bands

by anil-sn· code credited to QuantEdgeB

A chart-overlay trend filter that blends a slower smoothed moving average and a faster TEMA into one baseline, smooths it again with an EMA, and builds ATR bands around it.

View on GitHub

GitHub stars1on the repository
Pine versionv6current
Lines of code175
Settings8inputs
LicenceNone statedfile: MPL-2.0
Last update9 months ago5 Jan 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

175 lines of Pine Script v6 from pinecode/Referance/TwinSmooth ATR Bands.pine, published under MPL-2.0 (file header). Keep the author's credit and licence lines when you reuse it.

TwinSmooth ATR Bands.pine
// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © QuantEdgeB
// _____________________________________________________________________________________________
//                                                                                              |
//      ██████  ██    ██  █████  ███    ██ ████████ ███████ ██████   ██████  ███████ ██████     | 
//     ██    ██ ██    ██ ██   ██ ████   ██    ██    ██      ██   ██ ██       ██      ██   ██    |  
//     ██    ██ ██    ██ ███████ ██ ██  ██    ██    █████   ██   ██ ██   ███ █████   ██████     |   
//     ██ ▄▄ ██ ██    ██ ██   ██ ██  ██ ██    ██    ██      ██   ██ ██    ██ ██      ██   ██    | 
//      ██████   ██████  ██   ██ ██   ████    ██    ███████ ██████   ██████  ███████ ██████     |  
//         ▀▀                                                                                   |
//-----------------------------------------------------------------------------------------------                                                                                            
// 
// TwinSmooth ATR Bands | QuantEdgeB
// 
// 🔍 Overview
// TwinSmooth ATR Bands | QuantEdgeB is a dual-smoothing, ATR-adaptive trend filter that blends two complementary smoothing engines into a single baseline, then builds dynamic ATR bands around it to detect decisive breakouts. When price closes above the upper band it triggers a Long regime; when it closes below the lower band it flips to Short—otherwise it stays neutral. The script enhances clarity with regime-colored candles, an active-band fill, and an optional on-chart backtest table.
// 
// ✨ Key Features
// 1. 🧠 Twin-Smooth Baseline (Dual Engine Blend)
// - Computes two separate smoothed baselines (a slower “smooth” leg + a faster “responsive” leg).
// - Blends them into a single midpoint baseline for balanced stability + speed.
// - Applies an extra EMA smoothing pass to produce a clean trend_base.
// 2. 📏 ATR Volatility Bands
// - Builds upper/lower bands using ATR × multiplier around the trend_base.
// - Bands expand in volatile conditions and contract when markets quiet down—auto-adapting without manual tweaks.
// 3. ⚡ Clear Breakout Regime Logic
// - Long when close > upperBand.
// - Short when close < lowerBand.
// - Neutral otherwise (no forced signals inside the band zone).
// 4. 🎨 Visual Clarity
// - Plots only the active band (lower band in long regime, upper band in short regime).
// - Fills between active band and price for instant regime context.
// - Colors candles to match the current state (bullish / bearish / neutral).
// - Multiple color palettes + transparency control.
// 
// 
// 💼 Use Cases
// • Trend Confirmation Filter: Use the regime as a higher-confidence trend gate for entries from other indicators.
// • Breakout/Breakdown Trigger: Trade closes outside ATR bands to catch momentum expansions.
// • Volatility-Aware Stops/Targets: Bands naturally reflect volatility, making them useful as adaptive reference levels.
// • Multi-Timeframe Alignment: Confirm higher-timeframe regime before executing on lower timeframes.
// 
// 🎯 For Who
// • Trend Traders who want clean regime shifts without constant whipsaw.
// • Breakout Traders who prefer confirmation via ATR expansion rather than raw MA crossovers.
// • System Builders needing a simple, robust “state engine” (Long / Short / Neutral) to plug into larger strategies.
// • Analysts who want quick on-chart validation with a backtest table.
// 
// ⚙️ Default Settings
// • SMMA Length (Base Smooth Leg): 24
// • TEMA Length (Base Responsive Leg): 8
// • EMA Extra Smoothing: 14
// • ATR Length: 14
// • ATR Multiplier: 1.1
// • Color Mode: Alpha
// • Color Transparency: 30
// • Backtest Table: On (toggleable)
// • Backtest Start Date: 09 Oct 2017
// • Labels: Off by default
// 
// 📌 Conclusion
// TwinSmooth ATR Bands | QuantEdgeB merges a dual-speed smoothing core into a single trend baseline, then wraps it with ATR-based bands to deliver clean, volatility-adjusted breakout signals. With regime coloring, active-band plotting, and optional backtest stats, it’s a compact, readable tool for spotting momentum shifts and trend continuation across any market and timeframe.
// 
// 🔹 Disclaimer: Past performance is not indicative of future results. Always backtest and align settings with your risk tolerance and objectives before live trading.
// 🔹 Strategic Advice: Always backtest, optimize, and align parameters with your trading objectives and risk tolerance before live trading.
// 
//@version=6
indicator("TwinSmooth ATR Bands | QuantEdgeB",overlay = true)

import TradingView/ta/9
// Design Setup
LABEL   = input.bool(false,"Long/Cash Signal Lable" , group = "Visual | QuantEdgeB")
ColMode = input.string("Alpha", title = "Color Mode", group = "Visual | QuantEdgeB", options = ["Alpha","MultiEdge","TradingSuite", "Premium","Fundamental","Classic","Warm","Cold","Strategy" ])
ColOp = input.int(30,"Color Transperency", group = "Visual | QuantEdgeB",tooltip = "100 = Invisible")
[color_up, color_dn, color_nu] = switch ColMode
    "Alpha"        =>[#00ddff, color.rgb(219, 77, 12),color.gray]
    "MultiEdge"    => [color.rgb(2, 181, 184), color.rgb(185, 1, 202),color.gray]
    "TradingSuite" => [color.rgb(4, 208, 14), color.rgb(211, 248, 3),color.gray]
    "Premium"      => [color.rgb(49, 140, 252), color.rgb(144, 60, 208),color.gray]
    "Fundamental"  => [color.rgb(53, 220, 250), color.rgb(141, 6, 78),color.gray]
    "Warm"         => [#ffbb00, #770737,color.gray]
    "Cold"         => [color.rgb(109, 216, 255), color.rgb(34, 82, 255),color.gray]
    "Classic"      => [#04f7e7, color.rgb(190, 10, 52),color.gray]
    "Strategy"    => [color.rgb(0, 200, 255), color.rgb(122, 3, 3),color.rgb(140, 144, 160)]



// Color Palette
color col_up1     = color_up
color col_up2     = color.new(color_up,ColOp) 
color col_dn1     = color_dn
color col_dn2     = color.new(color_dn,ColOp)
color col_nu1     = color_nu
color col_nu2     = color.new(color_nu,ColOp)

//###############################################################################################################################################################################################################################################//
// Inputs
base_length    = input.int(24, "SMMA Length")
base2_length   = input.int(8, "TEMA Length")
ema_length     = input.int(14, "EMA Extra Smoothing")
atr_mult       = input.float(1.1, "ATR Multiplier", step = 0.1)
atr_len        = input.int(14, "ATR Length")

//###############################################################################################################################################################################################################################################//
// SMMA Function
F_SMMA(float src, int len) =>
    float smma = na
    if bar_index >= len - 1
        alpha = 1 / len
        smma := na(smma[1]) ? ta.sma(src, len) : (src - smma[1]) * alpha + smma[1]
        smma
    else
        smma := src
        smma
    smma

//###############################################################################################################################################################################################################################################//
// Base Calculation 
smma = F_SMMA(close, base_length)
tema  = ta.tema(close, base2_length)
base   = (smma + tema) / 2
trend_base = ta.ema(base, ema_length)

//###############################################################################################################################################################################################################################################//
// ATR Filter
atr        = ta.atr(atr_len)
upper_atr  = trend_base + atr * atr_mult
lower_atr  = trend_base - atr * atr_mult


//###############################################################################################################################################################################################################################################//
// Final Signal 
Long_C  = close > upper_atr
Short_C = close < lower_atr


var QB = 0

if Long_C and not Short_C
    QB := 1
    QB

if Short_C
    QB := -1
    QB

//###############################################################################################################################################################################################################################################//
//Plots
color = QB == 1 ? color_up : QB == -1 ? color_dn : color_nu
base_plot = plot(QB == 1 ? lower_atr : upper_atr, "Active Band", color = color.new(color, 10), linewidth = 1)

close_plot = plot(close, display = display.none)

fill(base_plot, close_plot, QB == 1 ? lower_atr : upper_atr, close, color.new(color, ColOp), na)
plotcandle(open, high, low, close, 'BarColor', color = color, bordercolor = color, wickcolor = color, force_overlay = true)
//###############################################################################################################################################################################################################################################//
// Plot Labels
if QB == -1 and QB[1] == -1 and  QB[2] == 1 and LABEL// Only plot when the signal changes
    label.new(x=bar_index, y= high * 1.08, text= "𝓢𝓱𝓸𝓻𝓽" , color=  color_dn, style=  label.style_label_down  ,textcolor=color.white, size=size.tiny)

if QB == 1 and QB[1] == 1 and  QB[2] == -1 and LABEL// Only plot when the signal changes
    label.new(x=bar_index, y= low * 0.9, text= "𝓛𝓸𝓷𝓰" , color=  color_up, style=  label.style_label_up  ,textcolor=color.white, size=size.tiny)

alertcondition(ta.crossover(QB, 0), title="TwinSmooth Long", message="TwinSmooth Long {{exchange}}:{{ticker}}")
alertcondition(ta.crossunder(QB, 0), title="TwinSmooth Short", message="TwinSmooth Short {{exchange}}:{{ticker}}")
//###############################################################################################################################################################################################################################################//
// _____________________________________________________________________________________________
//                                                                                              |
//      ██████  ██    ██  █████  ███    ██ ████████ ███████ ██████   ██████  ███████ ██████     | 
//     ██    ██ ██    ██ ██   ██ ████   ██    ██    ██      ██   ██ ██       ██      ██   ██    |  
//     ██    ██ ██    ██ ███████ ██ ██  ██    ██    █████   ██   ██ ██   ███ █████   ██████     |   
//     ██ ▄▄ ██ ██    ██ ██   ██ ██  ██ ██    ██    ██      ██   ██ ██    ██ ██      ██   ██    | 
//      ██████   ██████  ██   ██ ██   ████    ██    ███████ ██████   ██████  ███████ ██████     |  
//         ▀▀                                                                                   |
//-----------------------------------------------------------------------------------------------

Overview

A close above the upper band sets a long regime, a close below the lower band sets a short regime, and anything between stays neutral. Only the active band is drawn, with a fill, coloured candles and selectable palettes. Settings cover the SMMA, TEMA and EMA lengths and the ATR length and multiplier.

Details

Published by

anil-sn on GitHub

Code credit

QuantEdgeB, as written in the script's header

Draws

On the price chart

Markets

Any symbol

Timeframes

Any timeframe

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
Long/Cash Signal LableboolfalseLABEL
Color ModestringAlphaColMode
Color Transperencyint30ColOp
SMMA Lengthint24base_length
TEMA Lengthint8base2_length
EMA Extra Smoothingint14ema_length
ATR Multiplierfloat1.1atr_mult
ATR Lengthint14atr_len
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

318 stars

This indicator plots four customizable moving averages directly on the main price chart using default lengths of 3, 8, 21, and 50 periods. It fills the space between adjacent averages in green or maroon depending on trend alignment. Additionally, it computes B

Indicator v5 Moving averagesTrend
Updated 2 months ago · MIT GitHub repository of Multiple Moving Averages

NVDA Trend Ribbon

by longsurf-ai
280 stars

This indicator plots three exponential moving averages and ATR volatility envelopes on the price chart. It compares the fast and slow EMAs to shade a trend ribbon and marks confirmed upward and downward crossovers with triangle labels. Settings change the thre

Indicator v6 TrendMoving averages
Updated 3 days ago · MIT GitHub repository of NVDA Trend Ribbon

Bollinger Bands Force

by harryguiacorn
220 stars

This indicator modifies standard Bollinger Bands to measure directional trend force based on line alignment. It calculates a simple moving average basis along with upper and lower volatility bands. When all three lines move upward or downward simultaneously, i

Indicator v5 Volatility & bandsTrend
Updated 1 year ago · None stated GitHub repository of Bollinger Bands Force

Adaptive MA Slope

by capissimo
114 stars

This indicator calculates Kaufman's Adaptive Moving Average (KAMA) on a chosen price source and determines trend direction based on the slope across a configurable lookback window. Signals can be filtered by short-term volatility expansion using ATR comparison

Indicator v4 Moving averagesTrend
Updated 1 year ago · None stated GitHub repository of Adaptive MA Slope

More Trend scripts

Related on ForexR

Trade Your Charts With a Regulated Broker

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

Compare brokers