Indicator · Pine Script v6 · Own pane

Dynamic MAs ZSCORE

by vedkanani123· code credited to LyroRS

A separate-pane indicator that takes a selectable moving average of price, converts it to a Z-score over a lookback, and draws it against dynamic standard deviation bands with separate positive and negative multipliers.

View on GitHub

GitHub stars1on the repository
Pine versionv6current
Lines of code195
Settings12inputs
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

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

10.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("Dynamic MAs ZSCORE | Lyro RS", shorttitle = "Dynamic MAs ZSCORE | Lyro RS", overlay= false)

// Import Libraries
import LyroRS/LMAs/1 as DynamicMA

// Groups
core_g = "𝗖𝗢𝗥𝗘"
bands_g = "𝗕𝗔𝗡𝗗"
colors_g = '𝗖𝗢𝗟𝗢𝗥𝗦'

// CORE Inputs
source = input.source(close, "Source", tooltip="Select the data source for the indicator, typically the closing price.", group= core_g)
sig_type = input.string("Trend", "Signal", tooltip="Select the signal type, trend following or valuation.", options= ["Valuation", "Trend"] , group= core_g)
MA_Type = input.string("ALMA", "Select Moving Average", options=["SMA", "EMA", "WMA", "VWMA", "SMMA", "DEMA", "TEMA", "LSMA", "ZLSMA", "RMA", "HMA", "ALMA"], group=core_g, tooltip="Choose a moving average type to be applied in calculations.")
MA_len = input.int(3, "MA Length", tooltip="Set the length for the selected moving average. A higher value results in smoother movements.", group=core_g, minval=1)
zscore_len = input.int(30, "Z-Score Length", tooltip="Set the period for Z-Score calculation, determining trend strength.", group= core_g, minval=1)


// -- Bands
band_length = input.int(200, "Band Length", group=bands_g, tooltip="Number of bars used to calculate standard deviation.")
pbm = input.float(1.8, "Positive Band Multiplier", group=bands_g, minval=0, tooltip="Multiplier for the upper band distance.")
nbm = input.float(-0.85, "Negative Band Multiplier", group=bands_g, maxval=0, tooltip="Multiplier for the lower band distance.")


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

cpyn = input.bool(true, "Use Custom Palette", tooltip="Enable to manually define custom up/down colors for signals.", group= colors_g, display=display.none)
cp_UpC = input.color(#00ff00, "Custom Up", inline="Custom Palette", tooltip="Select a custom color for bullish signals.", group= colors_g, display=display.none)
cp_DnC = input.color(#ff0000, "Custom Down", inline="Custom Palette", tooltip="Select 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


// Moving Average Switch
float ma = na
switch MA_Type
    "SMA" => ma := DynamicMA.SMA(source, MA_len)
    "EMA" => ma := DynamicMA.EMA(source, MA_len)
    "WMA" => ma := DynamicMA.WMA(source, MA_len)
    "VWMA" => ma := DynamicMA.VWMA(source, volume, MA_len)
    "SMMA" => ma := DynamicMA.SMMA(source, MA_len)
    "DEMA" => ma := DynamicMA.DEMA(source, MA_len)
    "TEMA" => ma := DynamicMA.TEMA(source, MA_len)
    "LSMA" => ma := DynamicMA.LSMA(source, MA_len, 0)
    "ZLSMA" => ma := DynamicMA.ZLSMA(source, MA_len)
    "RMA" => ma := DynamicMA.RMA(source, MA_len)
    "HMA" => ma := DynamicMA.HMA(source, MA_len)
    "ALMA" => ma := DynamicMA.ALMA(source, MA_len, 0, 20)


// Dynamic Stdev Function
Stdev(float src, int period) =>
    actualPeriod = math.min(period, bar_index + 1) 
    mean         = DynamicMA.SMA(src, actualPeriod)
    sumSquares   = 0.0
    count = 0
    for i = 0 to actualPeriod - 1
        if not na(src[i])
            sumSquares := sumSquares + math.pow(nz(src[i]) - mean, 2)
            count := count + 1
    if count > 0
        math.sqrt(sumSquares / count)
    else
        na

// Dynamic Zscore Function
ZScore(float src, int lookback) =>
    ret_ = (src - DynamicMA.SMA(src, lookback)) / Stdev(src, lookback)
    ret_



// ZSCORE
ma_z = ZScore(ma, zscore_len)

// Calculations for the Bands
std          = Stdev(ma_z, band_length)
u = std * pbm 
l = std * nbm



// Coloring Function
coloring(src) =>
    color.from_gradient(src, -3, 3, UpC, DnC)


// Plot Color & BG color
var color pc = na
var color bg_col = na


// Valuation Mode
if sig_type == "Valuation"
    pc := coloring(ma_z)

    if ma_z <= -2
        bg_col := UpC

    else if ma_z >= 2
        bg_col := DnC

    else 
        bg_col := na


// Trend Mode
if sig_type == "Trend"
    if ta.crossover(ma_z, u)
        pc := UpC
    
    if ta.crossunder(ma_z, l)
        pc := DnC



is_between = ma_z <= u and ma_z >= l


main_line = plot(ma_z, 
 color=  sig_type == "Trend" ? (is_between ? color.new(pc,100) : color.new(pc,0)) : pc, 
 style= sig_type == "Valuation" ? plot.style_columns : plot.style_line, 
 linewidth= 5)

m2 = plot(ma_z, 
 color=  sig_type == "Trend" ? (is_between ? color.new(pc,100) : color.new(pc, 65)) : pc, 
 style= sig_type == "Valuation" ? plot.style_columns : plot.style_line, 
 linewidth= 10, display = display.pane)

plotshape(ma_z, style= shape.diamond, color= sig_type == "Trend" ? ma_z > u ? color.new(UpC, 60) :  ma_z < l ? color.new(DnC, 60) : na : na, location = location.absolute, size= size.small, display= display.pane)


// Defining the Value Zones
h3 = hline(-3, 'High Value Line', color = #29df4a9b, editable = false, display=  sig_type == "Valuation" ? display.all : display.none)
h2 = hline(-2, 'Slightly High Value Line', color = #0ba5b98d, editable = false, display=  sig_type == "Valuation" ? display.all : display.none)
h1 = hline(-1, 'Value Line', color = #3ca91881, editable = false, display=  sig_type == "Valuation" ? display.all : display.none)
h0 = hline(0, 'Zero Line Line', color = #7373758f, editable = false, display=  sig_type == "Valuation" ? display.all : display.none)
h4 = hline(1, 'Low Value Line', color = #ffe60070, editable = false, display=  sig_type == "Valuation" ? display.all : display.none)
h5 = hline(2, 'Slightly No Value Line', color = #c1620e86, editable = false, display=  sig_type == "Valuation" ? display.all : display.none)
h6 = hline(3, 'No Value Line', color = #910000, editable = false, display=  sig_type == "Valuation" ? display.all : display.none)

// Filling in Zones
fill(h5, h6, color = #a2000056, title= "Low Value Zone Highlight", display=  sig_type == "Valuation" ? display.all : display.none)
fill(h3, h2, color = #0d6e226e, title= "High Value Zone Highlight", display=  sig_type == "Valuation" ? display.all : display.none)


upper_zone = plot(u, "Upper Band", UpC, display=  sig_type == "Trend" ? display.all : display.none, editable = false, linewidth = 2)
lower_zone = plot(l, "Lower Band", DnC, display=  sig_type == "Trend" ? display.all : display.none, editable = false, linewidth = 2)

plot(u, "Upper Band", color.new(UpC, 75), display=  sig_type == "Trend" ? display.pane : display.none, editable = false, linewidth = 10)
plot(l, "Lower Band", color.new(DnC, 75), display=  sig_type == "Trend" ? display.pane : display.none, editable = false, linewidth = 10)


// Create the gradient fill effect
fill(main_line, upper_zone, ma_z, u, color.new(UpC, 60), color.new(chart.bg_color, 85), display=  sig_type == "Trend" ? display.all : display.none)
fill(main_line, lower_zone, ma_z, l, color.new(DnC, 60), color.new(chart.bg_color, 85), display=  sig_type == "Trend" ? display.all : display.none)


bgcolor(color.new(bg_col, 70), force_overlay = true)
barcolor(pc)
plotcandle(open, high, low, close, color=pc, wickcolor=pc, bordercolor=pc, title="Candles Coloring", display= display.pane, force_overlay = true)

alertcondition(ma_z > 0, "AI x MA ZSCORE - Long", "AI Optimized MA ZSCORE is Long {{exchange}}:{{ticker}}")
alertcondition(ma_z < 0, "AI x MA ZSCORE - Short", "AI Optimized MA ZSCORE is Short {{exchange}}:{{ticker}}")

alertcondition(ma_z > 0, "AI x MA ZSCORE - Over Valued", "AI Optimized MA ZSCORE is Over Valued {{exchange}}:{{ticker}}")
alertcondition(ma_z < 0, "AI x MA ZSCORE - Under Valued", "AI Optimized MA ZSCORE is Under Valued {{exchange}}:{{ticker}}")

Overview

Dynamic MAs ZSCORE can be read as a trend-following signal or as a valuation gauge showing stretched conditions. Inputs are the average type, its length, the Z-score length and the band length. Color palettes are selectable.

Details

Published by

vedkanani123 on GitHub

Code credit

LyroRS, as written in the script's header

Draws

Separate pane below the 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
Sourcesourceclosesource
SignalstringTrendsig_type
Select Moving AveragestringALMAMA_Type
MA Lengthint3MA_len
Z-Score Lengthint30zscore_len
Band Lengthint200band_length
Positive Band Multiplierfloat1.8pbm
Negative Band Multiplierfloat-0.85nbm
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

261 stars

This indicator calculates standardized z-scores of price data across four different lookback periods (6, 14, 26, and 100). Standardizing data subtracts the moving average from the price and divides by the standard deviation. It applies a Double Exponential Mov

Indicator v5 Mean reversionVolatility & bands
114 stars

This indicator calculates normalized percentage bounds around price highs and lows to anticipate local trend reversals. It oscillates within a fixed -1 to 1 channel and plots two boundary tracking curves alongside a background Karobein oscillator histogram for

Indicator v4 Mean reversionOscillators & momentum Repaints
Updated 1 year ago · None stated GitHub repository of Mean Reversion Indicator
99 stars

This indicator calculates the statistical autocorrelation coefficient of an input series over a user-defined lookback window at a specified lag. It tracks values using an internal circular buffer, computes sample mean, variance, and autocovariance, and normali

Indicator v6 TrendMean reversion
Updated 4 weeks ago · Apache-2.0 GitHub repository of Autocorrelation Function (ACF)

Pretty Good Oscillator

by mihakralj
47 stars

The Pretty Good Oscillator calculates the distance between the selected price source and its simple moving average, normalized by the Average True Range over a specified period. It renders as an oscillator line in a separate pane alongside a zero line and thre

Indicator v6 Oscillators & momentumMean reversion
Updated 8 months ago · MIT GitHub repository of Pretty Good Oscillator

Calculates a composite carry and decay oscillator fusing impulse-autocorrelation half-life, a Hurst exponent approximation, path efficiency, and range expansion ratios. It evaluates whether an impulse is likely to persist or mean-revert, plotting the oscillato

Indicator v6 TrendOscillators & momentum
Updated 3 days ago · MIT GitHub repository of Market Memory & Decay Oscillator [WavesUnchained]

More Oscillators & momentum 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