Indicator · Pine Script v5 · On the chart

Mean Reversion Channel - MRI Variant

by g-moe· code credited to goodgains

Calculates and plots a multi-band envelope on the price chart based on mean reversion principles and Keltner Channel concepts.

View on GitHub

GitHub stars3on the repository
Pine versionv5runs as is
Lines of code450
Settings17inputs
LicenceNone statedfile: MPL-2.0
Last update5 months ago27 May 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

450 lines of Pine Script v5 from Tradingview/mean-reversion-channel-mri-variant.pine, published under MPL-2.0 (file header). Keep the author's credit and licence lines when you reuse it.

mean-reversion-channel-mri-variant.pine
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © goodgains

// REUSING THIS CODE: You are welcome to reuse this code without permission, including in closed-source publications, as long as proper credits are given :)

// Description : 
// Mean Reversion Channel objective, based on Mean Reversion theory (everything has a tendency to revert back to its mean), is to help visualizing: 
//     Inner Channel -> Dynamic Support and Resistance 
//     Outer Channel -> Overbought/Oversold Zone which may signal consolidation phase or potential reversal due to unsustainable move

// The concept of this indicator oriiginally derived from Keltner Channel (The Keltner Channel was first introduced by Chester Keltner in the 1960s. The original formula used simple moving averages (SMA) and the high-low price range to calculate the bands. In the 1980s, a new formula was introduced that used ATR.)
// Instead if using SMA/EMA, this indicator used SuperSmoother MA as it's mean with longer lookback period (default to 200) to get more stable channel line. i also added second level so the indicator will have inner and outer channel
// Details of each filtering mrc_type used for mean calculation can be read in Ehlers Technical Papers: "Swiss Army Knife Indicator" and/or his book "Cybernetics Analysis for Stock and Futures"

// Disclaimer:
// Past performance is not an indicator of future results.
// My opinions are my own and do not constitute financial advice in any way whatsoever. 
// Nothing published by me constitutes an investment/trading recommendation, nor should any data or Content published by me be relied upon for any investment/trading activities.
// I strongly recommends that you perform your own independent research and/or speak with a qualified investment professional before making any financial decisions.

// Any ideas to further improve this indicator are welcome :)

//@version=5
indicator('Mean Reversion Channel - MRI Variant', shorttitle='MRC', overlay=true, format=format.inherit)

// @keywords: mean-reversion-channel-mri-variant, mrc, supersmoother-mean, inner-outer-channel, mean-reversion-bands, overbought-oversold-zone, dynamic-support-resistance, multi-timeframe-table, ehlers-filter-types, channel-zone-fill, line-extension, butterworth-gaussian-filter, bandstop-filter, mtf-analysis-panel, inherit-format-overlay, channel-multiplier, price-source-hlc3, zone-transparency, draw-channel-zones, stable-mean-line

//************************************************************************************************************
// Parameter
//************************************************************************************************************

indiSet = input(false, '═════════ MRC Parameter ════════')
source = input(hlc3, title='Price Source')
mrc_type = input.string('SuperSmoother', title='Filter Type', options=['SuperSmoother', 'Ehlers EMA', 'Gaussian', 'Butterworth', 'BandStop', 'SMA', 'EMA', 'RMA'])
length = input.int(200, title='Lookback Period', minval=1)
innermult = input.float(1.0, title='Inner Channel Size Multiplier', minval=0.1)
outermult = input.float(2.415, title='Outer Channel Size Multiplier', minval=0.1)

ChartSet = input(false, '═════════ Chart Setting ════════')
drawchannel = input(true, title='Draw Channel')
displayzone = input(true, title='Draw Zone (With Channel)')
zonetransp = input.int(60, title='Zone Transparency', minval=0, maxval=100)
displayline = input(true, title='Display Line Extension')

MTFSet = input(false, '═════════ MTF Setting ════════')
enable_mtf = input(true, title='Enable Multiple TimeFrame Analysis')
mtf_disp_typ = input.string('On Hover', title='MTF Display Type', options=['Always Display', 'On Hover'])
mtf_typ = input.string('Auto', title='Multiple TimeFrame Type', options=['Auto', 'Custom'])
mtf_lvl1 = input.timeframe('D', title='Custom MTF Level 1')
mtf_lvl2 = input.timeframe('W', title='Custom MTF Level 2')

//************************************************************************************************************
// Functions Start {
//************************************************************************************************************
var pi = 2 * math.asin(1)
var mult = pi * innermult
var mult2 = pi * outermult
var gradsize = 0.5
var gradtransp = zonetransp

//-----------------------
// Ehler SwissArmyKnife Function
//-----------------------
SAK_smoothing(_type, _src, _length) =>
    c0 = 1.0
    c1 = 0.0
    b0 = 1.0
    b1 = 0.0
    b2 = 0.0
    a1 = 0.0
    a2 = 0.0
    alpha = 0.0
    beta = 0.0
    gamma = 0.0
    cycle = 2 * pi / _length

    if _type == 'Ehlers EMA'
        alpha := (math.cos(cycle) + math.sin(cycle) - 1) / math.cos(cycle)
        b0 := alpha
        a1 := 1 - alpha
        a1
    if _type == 'Gaussian'
        beta := 2.415 * (1 - math.cos(cycle))
        alpha := -beta + math.sqrt(beta * beta + 2 * beta)
        c0 := alpha * alpha
        a1 := 2 * (1 - alpha)
        a2 := -(1 - alpha) * (1 - alpha)
        a2
    if _type == 'Butterworth'
        beta := 2.415 * (1 - math.cos(cycle))
        alpha := -beta + math.sqrt(beta * beta + 2 * beta)
        c0 := alpha * alpha / 4
        b1 := 2
        b2 := 1
        a1 := 2 * (1 - alpha)
        a2 := -(1 - alpha) * (1 - alpha)
        a2
    if _type == 'BandStop'
        beta := math.cos(cycle)
        gamma := 1 / math.cos(cycle * 2 * 0.1)  // delta default to 0.1. Acceptable delta -- 0.05<d<0.5
        alpha := gamma - math.sqrt(gamma * gamma - 1)
        c0 := (1 + alpha) / 2
        b1 := -2 * beta
        b2 := 1
        a1 := beta * (1 + alpha)
        a2 := -alpha
        a2
    if _type == 'SMA'
        c1 := 1 / _length
        b0 := 1 / _length
        a1 := 1
        a1
    if _type == 'EMA'
        alpha := 2 / (_length + 1)
        b0 := alpha
        a1 := 1 - alpha
        a1
    if _type == 'RMA'
        alpha := 1 / _length
        b0 := alpha
        a1 := 1 - alpha
        a1

    _Input = _src
    _Output = 0.0
    _Output := c0 * (b0 * _Input + b1 * nz(_Input[1]) + b2 * nz(_Input[2])) + a1 * nz(_Output[1]) + a2 * nz(_Output[2]) - c1 * nz(_Input[_length])
    _Output

//-----------------------
// SuperSmoother Function
//-----------------------
supersmoother(_src, _length) =>
    s_a1 = math.exp(-math.sqrt(2) * pi / _length)
    s_b1 = 2 * s_a1 * math.cos(math.sqrt(2) * pi / _length)
    s_c3 = -math.pow(s_a1, 2)
    s_c2 = s_b1
    s_c1 = 1 - s_c2 - s_c3
    ss = 0.0
    ss := s_c1 * _src + s_c2 * nz(ss[1], _src[1]) + s_c3 * nz(ss[2], _src[2])
    ss

//-----------------------
// Auto TimeFrame Function
//-----------------------
// ————— Converts current chart resolution into a float minutes value.
f_resInMinutes() =>
    _resInMinutes = timeframe.multiplier * (timeframe.isseconds ? 1. / 60 : timeframe.isminutes ? 1. : timeframe.isdaily ? 60. * 24 : timeframe.isweekly ? 60. * 24 * 7 : timeframe.ismonthly ? 60. * 24 * 30.4375 : na)
    _resInMinutes

get_tf(_lvl) =>
    y = f_resInMinutes()
    z = timeframe.period
    if mtf_typ == 'Auto'
        if y < 1
            z := _lvl == 1 ? '1' : _lvl == 2 ? '5' : z
            z
        else if y <= 3
            z := _lvl == 1 ? '5' : _lvl == 2 ? '15' : z
            z
        else if y <= 10
            z := _lvl == 1 ? '15' : _lvl == 2 ? '60' : z
            z
        else if y <= 30
            z := _lvl == 1 ? '60' : _lvl == 2 ? '240' : z
            z
        else if y <= 120
            z := _lvl == 1 ? '240' : _lvl == 2 ? 'D' : z
            z
        else if y <= 240
            z := _lvl == 1 ? 'D' : _lvl == 2 ? 'W' : z
            z
        else if y <= 1440
            z := _lvl == 1 ? 'W' : _lvl == 2 ? 'M' : z
            z
        else if y <= 10080
            z := _lvl == 1 ? 'M' : z
            z
        else
            z := z
            z
    else
        z := _lvl == 1 ? mtf_lvl1 : _lvl == 2 ? mtf_lvl2 : z
        z

    z

//-----------------------
// Mean Reversion Channel Function
//-----------------------
get_mrc() =>
    v_condition = 0
    v_meanline = source
    v_meanrange = supersmoother(ta.tr, length)

    //-- Get Line value
    if mrc_type == 'SuperSmoother'
        v_meanline := supersmoother(source, length)
        v_meanline

    if mrc_type != 'SuperSmoother'
        v_meanline := SAK_smoothing(mrc_type, source, length)
        v_meanline

    v_upband1 = v_meanline + v_meanrange * mult
    v_loband1 = v_meanline - v_meanrange * mult
    v_upband2 = v_meanline + v_meanrange * mult2
    v_loband2 = v_meanline - v_meanrange * mult2

    //-- Check Condition
    if close > v_meanline
        v_upband2_1 = v_upband2 + v_meanrange * gradsize * 4
        v_upband2_9 = v_upband2 + v_meanrange * gradsize * -4
        if high >= v_upband2_9 and high < v_upband2
            v_condition := 1
            v_condition
        else if high >= v_upband2 and high < v_upband2_1
            v_condition := 2
            v_condition
        else if high >= v_upband2_1
            v_condition := 3
            v_condition
        else if close <= v_meanline + v_meanrange
            v_condition := 4
            v_condition
        else
            v_condition := 5
            v_condition

    if close < v_meanline
        v_loband2_1 = v_loband2 - v_meanrange * gradsize * 4
        v_loband2_9 = v_loband2 - v_meanrange * gradsize * -4
        if low <= v_loband2_9 and low > v_loband2
            v_condition := -1
            v_condition
        else if low <= v_loband2 and low > v_loband2_1
            v_condition := -2
            v_condition
        else if low <= v_loband2_1
            v_condition := -3
            v_condition
        else if close >= v_meanline + v_meanrange
            v_condition := -4
            v_condition
        else
            v_condition := -5
            v_condition

    [v_meanline, v_meanrange, v_upband1, v_loband1, v_upband2, v_loband2, v_condition]

//-----------------------
// MTF Analysis
//-----------------------

get_stat(_cond) =>
    ret = 'Price at Mean Line\n'
    if _cond == 1
        ret := 'Overbought (Weak)\n'
        ret
    else if _cond == 2
        ret := 'Overbought\n'
        ret
    else if _cond == 3
        ret := 'Overbought (Strong)\n'
        ret
    else if _cond == 4
        ret := 'Price Near Mean\n'
        ret
    else if _cond == 5
        ret := 'Price Above Mean\n'
        ret
    else if _cond == -1
        ret := 'Oversold (Weak)\n'
        ret
    else if _cond == -2
        ret := 'Oversold\n'
        ret
    else if _cond == -3
        ret := 'Oversold (Strong)\n'
        ret
    else if _cond == -4
        ret := 'Price Near Mean\n'
        ret
    else if _cond == -5
        ret := 'Price Below Mean\n'
        ret
    ret

//-----------------------
// Chart Drawing Function
//-----------------------
format_price(x) =>
    y = str.tostring(x, '0.00000')
    if x > 10
        y := str.tostring(x, '0.000')
        y
    if x > 1000
        y := str.tostring(x, '0.00')
        y
    y

f_PriceLine(_ref, linecol) =>
    line.new(x1=bar_index, x2=bar_index - 1, y1=_ref, y2=_ref, extend=extend.left, color=linecol)

f_MTFLabel(_txt, _yloc) =>
    label.new(x=time + math.round(ta.change(time) * 20), y=_yloc, xloc=xloc.bar_time, text=mtf_disp_typ == 'Always Display' ? _txt : 'Check MTF', tooltip=mtf_disp_typ == 'Always Display' ? '' : _txt, color=color.black, textcolor=color.white, size=size.normal, style=mtf_disp_typ == 'On Hover' and displayline ? label.style_label_lower_left : label.style_label_left, textalign=text.align_left)

//} Function End

//************************************************************************************************************
// Calculate Channel
//************************************************************************************************************
var tf_0 = timeframe.period
var tf_1 = get_tf(1)
var tf_2 = get_tf(2)

[meanline, meanrange, upband1, loband1, upband2, loband2, condition] = get_mrc()
[mtf1_meanline, mtf1_meanrange, mtf1_upband1, mtf1_loband1, mtf1_upband2, mtf1_loband2, mtf1_condition] = request.security(syminfo.tickerid, tf_1, get_mrc())
[mtf2_meanline, mtf2_meanrange, mtf2_upband1, mtf2_loband1, mtf2_upband2, mtf2_loband2, mtf2_condition] = request.security(syminfo.tickerid, tf_2, get_mrc())

//************************************************************************************************************
// Drawing Start {
//************************************************************************************************************
float p_meanline = drawchannel ? meanline : na
float p_upband1 = drawchannel ? upband1 : na
float p_loband1 = drawchannel ? loband1 : na
float p_upband2 = drawchannel ? upband2 : na
float p_loband2 = drawchannel ? loband2 : na

z = plot(p_meanline, color=color.new(#FFCD00, 0), style=plot.style_line, title=' Mean', linewidth=2)
x1 = plot(p_upband1, color=color.new(color.green, 50), style=plot.style_circles, title=' R1', linewidth=1)
x2 = plot(p_loband1, color=color.new(color.green, 50), style=plot.style_circles, title=' S1', linewidth=1)
y1 = plot(p_upband2, color=color.new(color.red, 50), style=plot.style_line, title=' R2', linewidth=1)
y2 = plot(p_loband2, color=color.new(color.red, 50), style=plot.style_line, title=' S2', linewidth=1)

//-----------------------
// Draw zone
//-----------------------
//---
var color1 = #FF0000
var color2 = #FF4200
var color3 = #FF5D00
var color4 = #FF7400
var color5 = #FF9700
var color6 = #FFAE00
var color7 = #FFC500
var color8 = #FFCD00
//---
float upband2_1 = drawchannel and displayzone ? upband2 + meanrange * gradsize * 4 : na
float loband2_1 = drawchannel and displayzone ? loband2 - meanrange * gradsize * 4 : na
float upband2_2 = drawchannel and displayzone ? upband2 + meanrange * gradsize * 3 : na
float loband2_2 = drawchannel and displayzone ? loband2 - meanrange * gradsize * 3 : na
float upband2_3 = drawchannel and displayzone ? upband2 + meanrange * gradsize * 2 : na
float loband2_3 = drawchannel and displayzone ? loband2 - meanrange * gradsize * 2 : na
float upband2_4 = drawchannel and displayzone ? upband2 + meanrange * gradsize * 1 : na
float loband2_4 = drawchannel and displayzone ? loband2 - meanrange * gradsize * 1 : na
float upband2_5 = drawchannel and displayzone ? upband2 + meanrange * gradsize * 0 : na
float loband2_5 = drawchannel and displayzone ? loband2 - meanrange * gradsize * 0 : na
float upband2_6 = drawchannel and displayzone ? upband2 + meanrange * gradsize * -1 : na
float loband2_6 = drawchannel and displayzone ? loband2 - meanrange * gradsize * -1 : na
float upband2_7 = drawchannel and displayzone ? upband2 + meanrange * gradsize * -2 : na
float loband2_7 = drawchannel and displayzone ? loband2 - meanrange * gradsize * -2 : na
float upband2_8 = drawchannel and displayzone ? upband2 + meanrange * gradsize * -3 : na
float loband2_8 = drawchannel and displayzone ? loband2 - meanrange * gradsize * -3 : na
float upband2_9 = drawchannel and displayzone ? upband2 + meanrange * gradsize * -4 : na
float loband2_9 = drawchannel and displayzone ? loband2 - meanrange * gradsize * -4 : na

//---
plot_upband2_1 = plot(upband2_1, color=na, display=display.none, transp=100)
plot_loband2_1 = plot(loband2_1, color=na, display=display.none, transp=100)
plot_upband2_2 = plot(upband2_2, color=na, display=display.none, transp=100)
plot_loband2_2 = plot(loband2_2, color=na, display=display.none, transp=100)
plot_upband2_3 = plot(upband2_3, color=na, display=display.none, transp=100)
plot_loband2_3 = plot(loband2_3, color=na, display=display.none, transp=100)
plot_upband2_4 = plot(upband2_4, color=na, display=display.none, transp=100)
plot_loband2_4 = plot(loband2_4, color=na, display=display.none, transp=100)
plot_upband2_5 = plot(upband2_5, color=na, display=display.none, transp=100)
plot_loband2_5 = plot(loband2_5, color=na, display=display.none, transp=100)
plot_upband2_6 = plot(upband2_6, color=na, display=display.none, transp=100)
plot_loband2_6 = plot(loband2_6, color=na, display=display.none, transp=100)
plot_upband2_7 = plot(upband2_7, color=na, display=display.none, transp=100)
plot_loband2_7 = plot(loband2_7, color=na, display=display.none, transp=100)
plot_upband2_8 = plot(upband2_8, color=na, display=display.none, transp=100)
plot_loband2_8 = plot(loband2_8, color=na, display=display.none, transp=100)
plot_upband2_9 = plot(upband2_9, color=na, display=display.none, transp=100)
plot_loband2_9 = plot(loband2_9, color=na, display=display.none, transp=100)

//---
fill(plot_upband2_1, plot_upband2_2, color=color1, transp=gradtransp)
fill(plot_loband2_1, plot_loband2_2, color=color1, transp=gradtransp)
fill(plot_upband2_2, plot_upband2_3, color=color2, transp=gradtransp)
fill(plot_loband2_2, plot_loband2_3, color=color2, transp=gradtransp)
fill(plot_upband2_3, plot_upband2_4, color=color3, transp=gradtransp)
fill(plot_loband2_3, plot_loband2_4, color=color3, transp=gradtransp)
fill(plot_upband2_4, plot_upband2_5, color=color4, transp=gradtransp)
fill(plot_loband2_4, plot_loband2_5, color=color4, transp=gradtransp)
fill(plot_upband2_5, plot_upband2_6, color=color5, transp=gradtransp)
fill(plot_loband2_5, plot_loband2_6, color=color5, transp=gradtransp)
fill(plot_upband2_6, plot_upband2_7, color=color6, transp=gradtransp)
fill(plot_loband2_6, plot_loband2_7, color=color6, transp=gradtransp)
fill(plot_upband2_7, plot_upband2_8, color=color7, transp=gradtransp)
fill(plot_loband2_7, plot_loband2_8, color=color7, transp=gradtransp)
fill(plot_upband2_8, plot_upband2_9, color=color8, transp=gradtransp)
fill(plot_loband2_8, plot_loband2_9, color=color8, transp=gradtransp)

//-----------------------
// Plot Extension
//-----------------------
if displayline and enable_mtf and mtf_disp_typ == 'Always Display'
    displayline := false
    displayline

var line mean = na
line.delete(mean)
mean := displayline ? f_PriceLine(meanline, #FFCD00) : na
var line res1 = na
line.delete(res1)
res1 := displayline ? f_PriceLine(upband1, color.green) : na
var line sup1 = na
line.delete(sup1)
sup1 := displayline ? f_PriceLine(loband1, color.green) : na
var line res2 = na
line.delete(res2)
res2 := displayline ? f_PriceLine(upband2, color.red) : na
var line sup2 = na
line.delete(sup2)
sup2 := displayline ? f_PriceLine(loband2, color.red) : na

//--------------
// Prep MTF Label
//--------------
var brl = '\n--------------------------------------'
dist_0 = 'Distance from Mean: ' + str.tostring((close - meanline) / close * 100, '#.##') + ' %'
dist_1 = 'Distance from Mean: ' + str.tostring((close - mtf1_meanline) / close * 100, '#.##') + ' %'
dist_2 = 'Distance from Mean: ' + str.tostring((close - mtf2_meanline) / close * 100, '#.##') + ' %'

var title = 'Mean Reversion Channel\nMultiple TimeFrame Analysis' + brl
tf0 = '\n\nTimeframe: ' + tf_0 + ' (Current)\n\nStatus: ' + get_stat(condition) + dist_0 + brl

tf1 = not timeframe.ismonthly ? '\n\nTimeframe: ' + tf_1 + '\n\nStatus: ' + get_stat(mtf1_condition) + dist_1 + brl : ''

tf2 = not timeframe.isweekly and not timeframe.ismonthly ? '\n\nTimeframe: ' + tf_2 + '\n\nStatus: ' + get_stat(mtf2_condition) + dist_2 + brl : ''

mtf_lbl = title + tf0 + tf1 + tf2
var label label_mtf = na
label.delete(label_mtf)


label_mtf := enable_mtf ? f_MTFLabel(mtf_lbl, meanline) : na

//} Drawing End

Overview

Instead of standard moving averages, it uses advanced filters such as Ehlers SuperSmoother, Butterworth, Gaussian, or traditional averages as the baseline. It draws inner bands for dynamic support and resistance and outer bands to highlight potential overbought or oversold extremes. Settings allow customization of the filter type, lookback length, band multipliers, zone fills, and multiple timeframe analysis.

Details

Published by

g-moe on GitHub

Code credit

goodgains, as written in the script's header

Type

Indicator, Pine Script v5

Draws

On the price chart

Category

Mean reversion, Volatility & bands, Support & resistance, Moving averages

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
═════════ MRC Parameter ════════boolfalseindiSet
Price Sourcesourcehlc3source
Filter TypestringSuperSmoothermrc_type
Lookback Periodint200length
Inner Channel Size Multiplierfloat1.0innermult
Outer Channel Size Multiplierfloat2.415outermult
═════════ Chart Setting ════════boolfalseChartSet
Draw Channelbooltruedrawchannel
Draw Zone (With Channel)booltruedisplayzone
Zone Transparencyint60zonetransp
Display Line Extensionbooltruedisplayline
═════════ MTF Setting ════════boolfalseMTFSet
Show all 17 settings
SettingTypeDefaultVariable
Enable Multiple TimeFrame Analysisbooltrueenable_mtf
MTF Display TypestringOn Hovermtf_disp_typ
Multiple TimeFrame TypestringAutomtf_typ
Custom MTF Level 1timeframeDmtf_lvl1
Custom MTF Level 2timeframeWmtf_lvl2
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

This indicator plots trade entry and exit signals on the price chart by combining Bollinger Bands with optional filter conditions. It calculates standard Bollinger Bands along with RSI, Aroon, and moving average filters. Reversal signals trigger when price bre

Indicator v4 Volatility & bandsOscillators & momentum
Updated 2 months ago · None stated GitHub repository of Bollinger Bands Winner IND [Alorse]

Snag - VWAP

by dearvn
257 stars

This indicator plots a custom Anchored Volume-Weighted Average Price (VWAP) directly on the price chart along with optional standard deviation bands. Users can anchor the VWAP to standard time periods like sessions, weeks, or months, or to corporate events suc

Indicator v5 Moving averagesVolatility & bands Repaints
Updated 6 weeks ago · None stated GitHub repository of Snag - VWAP

MA Envelope (MAE)

by mihakralj
99 stars

The MA Envelope indicator calculates upper and lower channel bands shifted by a user-defined percentage around a baseline moving average. It supports Simple Moving Average, Exponential Moving Average, and Weighted Moving Average calculation types. The script p

Indicator v6 Moving averagesSupport & resistance
Updated 4 weeks ago · Apache-2.0 GitHub repository of MA Envelope (MAE)

Moon Dev GEX Walls & Trap

by moondevonyt
92 stars

This indicator estimates gamma exposure levels and intraday context for index instruments like SPY and ES. It calculates VWAP with standard deviation bands as a gamma flip proxy, highlighting market regimes through background colors. It plots prior day high, l

Indicator v5 Support & resistanceSessions & time
Updated 8 weeks ago · Custom licence GitHub repository of Moon Dev GEX Walls & Trap
55 stars

This Pine Script indicator overlays institutional liquidity levels on the price chart. It identifies order block levels using pivot highs and lows, then draws mean reversion lines from the 20 and 50 period simple moving averages, a volatility range midpoint pr

Indicator v6 Support & resistanceSMC / ICT / price action Repaints
Updated 6 months ago · Apache-2.0 GitHub repository of AAPL Institutional Liquidity Grid

More indicators

Trade Your Charts With a Regulated Broker

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

Compare brokers