Indicator · Pine Script v6 · Own pane

Mean Deviation Loop

by vedkanani123· code credited to LyroRS

A separate-pane oscillator based on mean absolute deviation.

View on GitHub

GitHub stars1on the repository
Pine versionv6current
Lines of code362
Settings22inputs
LicenceNone statedfile: MPL-2.0
Last update2 months ago23 Aug 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

362 lines of Pine Script v6 from indicator/olg_7_6_26/LyroRS/8.txt, published under MPL-2.0 (file header). Keep the author's credit and licence lines when you reuse it.

8.txt
// This Pine Script® code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © LyroRS

//@version=6
indicator("Mean Deviation Loop | Lyro RS", "MAD Loop | Lyro RS",overlay = false)


//─────────────────────────────────────────────────────────────────────────────────────────────────────────────
//─██████─────────████████──████████─████████████████───██████████████───────████████████████───██████████████─
//─██░░██─────────██░░░░██──██░░░░██─██░░░░░░░░░░░░██───██░░░░░░░░░░██───────██░░░░░░░░░░░░██───██░░░░░░░░░░██─
//─██░░██─────────████░░██──██░░████─██░░████████░░██───██░░██████░░██───────██░░████████░░██───██░░██████████─
//─██░░██───────────██░░░░██░░░░██───██░░██────██░░██───██░░██──██░░██───────██░░██────██░░██───██░░██─────────
//─██░░██───────────████░░░░░░████───██░░████████░░██───██░░██──██░░██───────██░░████████░░██───██░░██████████─
//─██░░██─────────────████░░████─────██░░░░░░░░░░░░██───██░░██──██░░██───────██░░░░░░░░░░░░██───██░░░░░░░░░░██─
//─██░░██───────────────██░░██───────██░░██████░░████───██░░██──██░░██───────██░░██████░░████───██████████░░██─
//─██░░██───────────────██░░██───────██░░██──██░░██─────██░░██──██░░██───────██░░██──██░░██─────────────██░░██─
//─██░░██████████───────██░░██───────██░░██──██░░██████─██░░██████░░██───────██░░██──██░░██████─██████████░░██─
//─██░░░░░░░░░░██───────██░░██───────██░░██──██░░░░░░██─██░░░░░░░░░░██───────██░░██──██░░░░░░██─██░░░░░░░░░░██─
//─██████████████───────██████───────██████──██████████─██████████████───────██████──██████████─██████████████─
//─────────────────────────────────────────────────────────────────────────────────────────────────────────────
//                                                 LyroRS v1.0


// Library
import TradingView/ta/9 as ta
import LyroRS/LMAs/1 as DynamicMA


// Input Groups
indi_settings_g = "𝗜𝗡𝗗𝗜𝗖𝗔𝗧𝗢𝗥 𝗦𝗘𝗧𝗧𝗜𝗡𝗚𝗦"
bb_g = "𝗕𝗢𝗟𝗟𝗜𝗡𝗚𝗘𝗥 𝗕𝗔𝗡𝗗𝗦"
fl_g = "𝗙𝗢𝗥 𝗟𝗢𝗢𝗣"
combined_sig_g = "𝗖𝗢𝗠𝗕𝗜𝗡𝗘𝗗 𝗦𝗜𝗚𝗡𝗔𝗟"
table_g = "𝗧𝗔𝗕𝗟𝗘"
colors_g = "𝗖𝗢𝗟𝗢𝗥𝗦"



// Inputs

// -- Indicator Settings
source = input.source(close, "Source", tooltip="Select the price source (e.g., close, open, high, low) used for calculations.", group= indi_settings_g)

signal_mode = input.string("Bollinger Bands", "Signal Mode", 
 tooltip="Select the logic used to generate signals: BB, Loop, or Combined Signal.",
 group=indi_settings_g, 
 options=["Bollinger Bands", "For Loop", "Combined Signal"])


// -- BB
ma_benchmark_type_bb = input.string("EMA", "Select Moving Average BB", options=["SMA", "EMA", "WMA", "VWMA", "DEMA", "TEMA", "RMA", "HMA", "LSMA", "SMMA", "ALMA", "ZLSMA", "FRAMA", "KAMA", "JMA", "T3"], group=bb_g, tooltip="Choose a moving average type to be applied in calculations.")
mad_length_bb = input.int(25, "BB MA Length", tooltip="The lookback period for calculating the Mean Absolute Deviation (MAD) around the selected moving average (for Bollinger Band style calculation).", group=bb_g)
mad_multp = input.float(1.4, "+ Multiplier", tooltip="A multiplier applied to the MAD distance from the average to create upper MAD band.", group=bb_g)
mad_multn = input.float(1, "- Multiplier", tooltip="A multiplier applied to the MAD distance from the average to create lower MAD band.", group=bb_g)


// -- For Loop
ma_benchmark_type_fl = input.string("ALMA", "Select Moving Average BB", options=["SMA", "EMA", "WMA", "VWMA", "DEMA", "TEMA", "RMA", "HMA", "LSMA", "SMMA", "ALMA", "ZLSMA", "FRAMA", "KAMA", "JMA", "T3"], group=fl_g, tooltip="Select a moving average type used in For Loop calculations.")
mad_length_fl = input.int(10, "For Loop Length", tooltip="The lookback period for calculating the Mean Absolute Deviation (MAD) around the selected moving average (for loop style calculation).", group=fl_g)

a_ = input.int(10, "From", tooltip="Sets the starting index for the loop iteration.", group=fl_g)
b_ = input.int(60, "To", tooltip="Sets the ending index for the loop iteration.", group=fl_g)

Threshold_L_Fl = input.int(23, "Threshold Long", step=1, tooltip="Defines the threshold level above which an uptrend is detected.", group=fl_g)
Threshold_S_Fl = input.int(3, "Threshold Short", step=1, tooltip="Defines the threshold level below which a downtrend is detected.", group=fl_g)


// -- Combined Signal
Threshold_L_C = input.float(0, "Threshold Long", step=0.01, 
 tooltip="Combined signal must be ≥ this to trigger a long signal.", 
 group=combined_sig_g, maxval=1, minval=0)

Threshold_S_C = input.float(0, "Threshold Short", step=0.01, 
 tooltip="Combined signal must be < this to trigger a short signal.", 
 group=combined_sig_g, maxval=0, minval=-1)



// -- Tables
fo = input.bool(false, 'Force Table Overlay', display = display.none, group =table_g, tooltip = 'Allows forcing the overlay of the table on the chart.')
enable_table = input.bool(true, '', display = display.none, group =table_g, inline= "T")
pos_table = input.string('Middle Right', 'MAD Trend Modes Table', options = ['Top Left', 'Middle Left', 'Bottom Left', 'Top Right', 'Middle Right', 'Bottom Right', 'Top Center', "Middle Center", 'Bottom Center'], group = table_g, display = display.none, inline= "T")
table_size_input = input.string("Normal", '', options= ["Huge", "Large", "Normal", "Small", "Tiny"], group= table_g, tooltip= "Settings for the MAD Trend Modes table.", display = display.none, inline= "T")




// Color Inputs
ColMode = input.string("Mystic", "Custom Color Palette", inline="drop", options=["Classic", "Mystic", "Accented", "Royal"], display=display.none, group=colors_g,  tooltip="Choose a predefined color scheme for indicator visualization.")

cpyn = input.bool(true, "Use Custom Palette", tooltip= "Enable manual selection of custom colors for trend signals.", group=colors_g, display=display.none)
cp_UpC = input.color(#00ff00, "Custom Up", inline= "Custom Palette", tooltip= "Set a custom color for bullish signals.", group=colors_g, display=display.none)
cp_DnC = input.color(#ff0000, "Custom Down", inline= "Custom Palette", tooltip= "Set a custom color for bearish signals.", group=colors_g, display=display.none)



// Colors
color UpC = na
color DnC = na

switch ColMode
    "Classic" =>
        UpC := #00E676
        DnC := #880E4F
    "Mystic" =>
        UpC := #30FDCF
        DnC := #E117B7
    "Accented" =>
        UpC := #9618F7
        DnC := #FF0078
    "Royal" =>
        UpC := #FFC107
        DnC := #673AB7


if cpyn
    UpC := cp_UpC
    DnC := cp_DnC




// Table

// -- Defining Table Size
var string table_size = na


// -- Switching Table Size
switch table_size_input
    "Huge" =>
        table_size := size.huge
    "Large" =>
        table_size :=  size.large
    "Normal" =>
        table_size :=  size.normal
    "Small" =>
        table_size :=  size.small
    "Tiny" =>
        table_size :=  size.tiny


// -- Position Switching
pot(position) =>
    var pos = switch position
        'Top Left' => position.top_left
        'Middle Left' => position.middle_left
        'Bottom Left' => position.bottom_left
        'Top Right' => position.top_right
        'Middle Right' => position.middle_right
        'Bottom Right' => position.bottom_right
        'Top Center' => position.top_center
        "Middle Center" => position.middle_center
        'Bottom Center' => position.bottom_center
    pos


// Mean Absolute Deviation Function
mad(src, benchmark, length) =>
    sum_abs_diff = 0.0
    for i = 0 to length - 1
        diff = math.abs(src[i] - benchmark)
        sum_abs_diff := sum_abs_diff + diff
    sum_abs_diff / length


// For Loop
system(src, a, b) =>
    total  = 0.0
    for i  = a to b by 1
        total += (src > src[i] ? 1 : -1)
        total
    total



// Moving Average Switch
ma_switch(src, length, avg_type) =>
    avg = switch avg_type
        "SMA" =>    DynamicMA.SMA(src, length)
        "EMA" =>    DynamicMA.EMA(src, length)
        "WMA" =>    DynamicMA.WMA(src, length)
        "VWMA" =>   DynamicMA.VWMA(src, volume, length)
        "DEMA" =>   DynamicMA.DEMA(src, length)
        "TEMA" =>   DynamicMA.TEMA(src, length)
        "RMA" =>   DynamicMA.RMA(src, length)
        "HMA" =>    DynamicMA.HMA(src, length)
        "LSMA" =>   DynamicMA.LSMA(src, length, 0)
        "SMMA" =>   DynamicMA.SMMA(src, length)
        "ALMA" =>   DynamicMA.ALMA(src, length, 0, 20)
        "ZLSMA" =>  DynamicMA.ZLSMA(src, length)
        "FRAMA" =>  DynamicMA.FRAMA(src, length)
        "KAMA" =>   DynamicMA.KAMA(src, length)
        "JMA" =>   DynamicMA.JMA(src, length, 0.5)
        "T3" =>   DynamicMA.T3(src, length, 0.5)


// Final Processing

// -- Defining Variables
avg_bb = ma_switch(source, mad_length_bb, ma_benchmark_type_bb)
avg_fl = ma_switch(source, mad_length_fl, ma_benchmark_type_fl)

mad_value = mad(source, avg_bb, mad_length_bb)
mad2 = mad(source, avg_fl, mad_length_fl)


// -- BB 
bb_positive_band = avg_bb + (mad_value * mad_multp)
bb_negative_band = avg_bb - (mad_value * mad_multn)


// For Loop
mad_w_src =  ma_switch(source*mad2, mad_length_fl, ma_benchmark_type_fl) / ma_switch(mad2, mad_length_fl, ma_benchmark_type_fl) // MAD combined with the source of the indicator
mad_fl = system(mad_w_src, a_, b_)


// Score Variable
var int score = 0
var int bb_score = 0
var int fl_score = 0
var int combined_signal = 0

// Conditions
// -- BB
if ta.crossover(source, bb_positive_band)
    bb_score := 1

if ta.crossunder(source, bb_negative_band)
    bb_score := -1



if signal_mode == "Bollinger Bands"
    if ta.crossover(source, bb_positive_band)
        score := 1

    if ta.crossunder(source, bb_negative_band)
        score := -1


// -- FL
if ta.crossover(mad_fl, Threshold_L_Fl)
    fl_score := 1

if ta.crossunder(mad_fl, Threshold_S_Fl)
    fl_score := -1



if signal_mode == "For Loop"
    if ta.crossover(mad_fl, Threshold_L_Fl)
        score := 1

    if ta.crossunder(mad_fl, Threshold_S_Fl)
        score := -1



// -- Combined Signal
c_signal = math.avg(bb_score, fl_score)

if ta.crossover(c_signal, Threshold_L_C)
    combined_signal := 1


if ta.crossunder(c_signal, Threshold_S_C)
    combined_signal := -1



if signal_mode == "Combined Signal"
    if ta.crossover(c_signal, Threshold_L_C)
        score := 1

    if ta.crossunder(c_signal, Threshold_S_C)
        score := -1




// Plot Color
pc = score == 1 ? UpC : score == -1 ? DnC : color.gray
pc_bb = bb_score == 1 ? UpC : bb_score == -1 ? DnC : color.gray
pc_fl = fl_score == 1 ? UpC : fl_score == -1 ? DnC : color.gray
pc_combined = combined_signal == 1 ? UpC : combined_signal == -1 ? DnC : color.gray



// Tables
var table mode_stat_table = na


// -- Force Overlay Conditions
if fo // 'fo' is an input, but used in an if block, not directly in table.new
    mode_stat_table := table.new(pot(pos_table), 100, 100, frame_width = 1, frame_color = color.gray, force_overlay = true, border_color = color.gray, border_width = 1)

else
    mode_stat_table := table.new(pot(pos_table), 100, 100, frame_width = 1, frame_color = color.gray, force_overlay = false, border_color = color.gray, border_width = 1)



// -- Table Cells
if enable_table
    table.cell(mode_stat_table, 0, 0, 'MAD Trend Modes Table | 𝓛𝓎𝓇𝓸 𝓡𝓢', text_color = color.white, bgcolor = #000000, text_size=table_size)
    table.cell(mode_stat_table, 1, 0, '', text_color = color.white, bgcolor = #000000, text_size=table_size)


    table.cell(mode_stat_table, 0, 1, 'Modes:', text_color = color.white, bgcolor = #000000, text_size=table_size)
    table.cell(mode_stat_table, 0, 2, 'Bollinger Bands', text_color = color.gray, bgcolor = #000000, text_size=table_size)
    table.cell(mode_stat_table, 0, 3, 'For Loop', text_color = color.gray, bgcolor = #000000, text_size=table_size)
    table.cell(mode_stat_table, 0, 4, 'Combined Signal', text_color = color.gray, bgcolor = #000000, text_size=table_size)

    table.cell(mode_stat_table, 1, 1, 'Signals:', text_color = color.white, bgcolor = #000000, text_size=table_size)
    table.cell(mode_stat_table, 1, 2, bb_score == 1 ? "⬆️Long ⬆️" : bb_score == -1 ? "⬇️Short ⬇️" : na, text_color = pc_bb, bgcolor = #000000, text_size=table_size)
    table.cell(mode_stat_table, 1, 3, fl_score == 1 ? "📈Up 📈" : fl_score == -1 ? "📉Down 📉" : na, text_color = pc_fl, bgcolor = #000000, text_size=table_size)
    table.cell(mode_stat_table, 1, 4, combined_signal == 1 ? "🚀Up-Trend 🚀" : combined_signal == -1 ? "🪂 Down-Trend 🪂" : na , text_color = pc_combined, bgcolor = #000000, text_size=table_size)

    table.merge_cells(mode_stat_table, 0, 0, 1, 0)






// Plots

// -- Bollinger Bands Plot
plot(bb_positive_band, color= color.new(UpC, 50), title= "Positive Band", display= display.pane + display.price_scale, force_overlay = true)
plot(bb_negative_band, color= color.new(DnC, 50), title= "Negative Band", display= display.pane + display.price_scale, force_overlay = true)
plot(avg_bb, color= pc_bb, title= "Moving Average", force_overlay = true)
plot(avg_bb, color = color.new(pc_bb, 85), title= "Bollinger Bands Glow Effect 1", linewidth = 10, force_overlay = true, display= display.pane)


// -- For Loop Plot
plot(mad_fl, color = pc_fl, title= "MAD For Loop")
plot(mad_fl, color = color.new(pc_fl, 75), title= "For Loop Glow Effect", linewidth = 10, display= display.pane)



plot(Threshold_L_Fl, color = UpC, title= "Long Threshold", display= display.pane)
plot(Threshold_S_Fl, color = DnC, title= "Short Threshold", display= display.pane)


plotshape(ta.crossover(score, 0), title="Buy Signal", location=location.belowbar,
           style=shape.labelup, text="𝓛𝓸𝓷𝓰", textcolor=#000000, size=size.small,
           color=UpC, force_overlay=true, display= display.pane)

plotshape(ta.crossunder(score, 0), title="Sell Signal", location=location.abovebar,
           style=shape.labeldown, text="𝓢𝓱𝓸𝓻𝓽", textcolor=#000000, size=size.small,
           color=DnC, force_overlay=true, display= display.pane)




barcolor(pc)
plotcandle(open, high, low, close, color= pc, wickcolor=pc, bordercolor = pc, force_overlay = true, title= "Plot Candle", display=display.pane)


// Alerts
alertcondition(score == 1 and score[1] != 1, "Mean Absolute Deviation Trend - Long", "Mean Absolute Deviation Trend is Long {{exchange}}:{{ticker}}")
alertcondition(score == -1 and score[1] != -1, "Mean Absolute Deviation Trend - Short", "Mean Absolute Deviation Trend is Short {{exchange}}:{{ticker}}")

Overview

Mean Deviation Loop offers two signal modes: Bollinger-style bands around a chosen moving average of the deviation, or a for-loop score summed across a range of lookbacks and compared with long and short thresholds. The line is colored by trend state. A table can show the active modes and signal state, and several moving average types and color palettes are available.

Details

Published by

vedkanani123 on GitHub

Code credit

LyroRS, as written in the script's header

Type

Indicator, Pine Script v6

Draws

Separate pane below the chart

Category

Oscillators & momentum, Volatility & bands

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
Sourcesourceclosesource
Signal ModestringBollinger Bandssignal_mode
Select Moving Average BBstringEMAma_benchmark_type_bb
BB MA Lengthint25mad_length_bb
+ Multiplierfloat1.4mad_multp
- Multiplierfloat1mad_multn
Select Moving Average BBstringALMAma_benchmark_type_fl
For Loop Lengthint10mad_length_fl
Fromint10a_
Toint60b_
Threshold Longint23Threshold_L_Fl
Threshold Shortint3Threshold_S_Fl
Show all 22 settings
SettingTypeDefaultVariable
Threshold Longfloat0Threshold_L_C
Threshold Shortfloat0Threshold_S_C
Force Table Overlayboolfalsefo
enable_tablebooltrueenable_table
MAD Trend Modes TablestringMiddle Rightpos_table
table_size_inputstringNormaltable_size_input
Custom Color PalettestringMysticColMode
Use Custom Palettebooltruecpyn
Custom Upcolor#00ff00cp_UpC
Custom Downcolor#ff0000cp_DnC
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

TTM Squeeze

by Alorse
330 stars

This indicator plots a TTM Squeeze momentum oscillator in a separate pane. It compares a Bollinger Band offset to a Keltner Channel offset and marks the zero line white when the difference is non-negative and black when the bands are inside the channel. A line

Indicator v5 Oscillators & momentumVolatility & bands
Updated 2 months ago · None stated GitHub repository of TTM Squeeze

Function - Logistic Equation

by ricardosantos79
261 stars

Calculates dynamic modeling values by applying a mathematical logistic differential equation to price change over a specified lookback length. It measures price momentum relative to the recent high-low price range. The script plots positive and negative logist

Indicator v5 Oscillators & momentumVolatility & bands
Updated 4 years ago · None stated GitHub repository of Function - Logistic Equation

MACD-V

by harryguiacorn
219 stars

MACD-V is a volatility-normalized momentum indicator based on research by Alex Spiroglou. It calculates the standard MACD histogram and normalizes it by dividing by the Average True Range (ATR). Plotted in a separate pane as a colored histogram, it includes us

Indicator v5 Oscillators & momentumVolatility & bands
Updated 1 year ago · None stated GitHub repository of MACD-V
218 stars

This indicator detects a Bollinger Band squeeze when the bands sit inside Keltner Channels, marking low volatility. It plots red dots during a squeeze and green dots when the bands are outside, in a separate pane. An optional histogram shows momentum as the cl

Indicator v6 Volatility & bandsOscillators & momentum
Updated 3 months ago · None stated GitHub repository of Bollinger Band Squeeze Detector
147 stars

This indicator generates trade entry signals and target levels optimized for 1-hour timeframes, designed for external signal extraction. It calculates 7-period and 16-period EMAs alongside 10-period RSI and ATR filters. Long signals occur when the fast EMA cro

Indicator v5 TrendOscillators & momentum
Updated 6 weeks ago · MIT GitHub repository of Signal Strategy 100 Candles of 1H Timeframe

Bubbles Indicator

by capissimo
114 stars

The Bubbles Indicator measures volatility squeezes and expansion bursts using Bollinger Bands combined with a sinusoid oscillator and RSI divergence. It processes price data through scaled Bollinger Bands to highlight volatility changes while confirming trend

Indicator v4 Volatility & bandsOscillators & momentum Repaints
Updated 1 year ago · None stated GitHub repository of Bubbles Indicator

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