Indicator · Pine Script v6 · Own pane

Grid Bot Z-Score [psyll]

by cullyk· code credited to Copyright

This Pine Script indicator calculates Z-Score based bands for grid trading using a user-selectable moving average.

View on GitHub

Repaints

GitHub stars2on the repository
Pine versionv6current
Lines of code90
Settings15inputs
LicenceMIT
Last update8 months ago25 Feb 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

90 lines of Pine Script v6 from plugins/Grid Bot [Grid range plugin] Z-Score [psyll].pine, published under MIT. Keep the author's credit and licence lines when you reuse it.

Grid Bot [Grid range plugin] Z-Score [psyll].pine
//@version=6
// Author: Psyll.com
// Email: info@psyll.com
// Website: https://psyll.com
// Copyright: Copyright © 2025 psyll.com. All rights reserved.
indicator('Grid Bot [Grid range plugin] Z-Score [psyll]', overlay = false)
ma(ma_type, ma_source, ma_length) =>
    float result = 0
    if ma_type == 'EMA'
        result := ta.ema(ma_source, ma_length)
        result
    if ma_type == 'SMA'
        result := ta.sma(ma_source, ma_length)
        result
    if ma_type == 'WMA'
        result := ta.wma(ma_source, ma_length)
        result
    if ma_type == 'HMA'
        result := ta.hma(ma_source, ma_length)
        result
    if ma_type == 'RMA'
        result := ta.rma(ma_source, ma_length)
        result
    if ma_type == 'VWMA'
        result := ta.vwma(ma_source, ma_length)
        result
    if ma_type == 'DEMA'
        result := 2 * ta.ema(ma_source, ma_length) - ta.ema(ta.ema(ma_source, ma_length), ma_length)
        result
    if ma_type == 'TEMA'
        result := 3 * (ta.ema(ma_source, ma_length) - ta.ema(ta.ema(ma_source, ma_length), ma_length)) + ta.ema(ta.ema(ta.ema(ma_source, ma_length), ma_length), ma_length)
        result
    if ma_type == 'ZLEMA'
        result := ta.ema(ma_source + ma_source - ma_source[(ma_length - 1) / 2], ma_length)
        result
    result
decimal_places = 0
tick_size = syminfo.mintick
while tick_size < 1
    tick_size := tick_size * 10
    decimal_places := decimal_places + 1
    decimal_places
settings_group = 'Settings #################################################'
ma_type = input.string('SMA', 'Type', options = ['SMA', 'EMA', 'WMA', 'HMA', 'RMA', 'VWMA', 'DEMA', 'TEMA', 'ZLEMA'], group = settings_group, display = display.none)
length = input.int(500, 'Length', minval = 1, group = settings_group, display = display.none)
source = input.source(defval = close, title = 'Source', group = settings_group, display = display.none)
stddevs = input.float(1.69, 'Stddevs', group = settings_group, display = display.none)
offset = input.float(1, 'Offset', group = settings_group, display = display.none)
width_min = input.float(0, 'Min width', group = settings_group, display = display.none)
width_max = input.float(99999, 'Max width', group = settings_group, display = display.none)
width_min_half = width_min / 2
width_max_half = width_max / 2
tf_group = 'Timeframe ###############################################'
tf_confirmation_wait = input.bool(defval = true, title = 'Wait for confirm', group = tf_group, inline = tf_group, display = display.none)
tf_no_repaint_security = input.bool(defval = true, title = 'No repaint', group = tf_group, inline = tf_group, display = display.none)
tf_barmerge_lookahead = input.bool(defval = false, title = 'Lookahead', group = tf_group, inline = tf_group, display = display.none)
tf_barmerge_gaps = input.bool(defval = false, title = 'Gaps', group = tf_group, inline = tf_group, display = display.none)
tf_type = input.string(title = 'Type', options = ['Static', 'Custom'], defval = 'Static', group = tf_group, display = display.none)
tf_static = input.timeframe(defval = '', title = 'Static', group = tf_group, display = display.none)
tf_custom = str.tostring(input.int(1, 'Custom', group = tf_group, display = display.none))
tf_type_value = switch tf_type
    'Static' => tf_static
    'Custom' => tf_custom
tf_security(source) =>
    request.security(syminfo.tickerid, tf_type_value, tf_no_repaint_security ? source[barstate.isrealtime ? 1 : 0] : source, gaps = tf_barmerge_gaps ? barmerge.gaps_on : barmerge.gaps_off, lookahead = tf_barmerge_lookahead ? barmerge.lookahead_on : barmerge.lookahead_off)[tf_no_repaint_security ? barstate.isrealtime ? 0 : 1 : 0]
display_group = 'Display ##################################################'
price_color = input.color(color.black, 'Candles color', display = display.none, group = display_group)
// Plot pricecandle
plotcandle(open, high, low, close, color = price_color, bordercolor = price_color, wickcolor = price_color, display = display.pane)
basis = tf_security(ma(ma_type, source, length))
zscore = (source - basis) / tf_security(ta.stdev(source, length))
diff = math.abs(source - basis)
absZscore = math.abs(zscore)
bounds = diff / absZscore * stddevs
grid_high = basis + bounds
grid_low = basis - bounds
grid_high := grid_high + offset
grid_low := grid_low - offset
grid_middle = (grid_high + grid_low) / 2
if grid_high - grid_low < width_min
    grid_high := grid_middle + width_min_half
    grid_low := grid_middle - width_min_half
    grid_low
if grid_high - grid_low > width_max
    grid_high := grid_middle - width_max_half
    grid_low := grid_middle + width_max_half
    grid_low
plot(grid_high, 'High', color.green, display = display.all)
plot(grid_middle, 'Middle', color.silver, display = display.pane)
plot(grid_low, 'Low', color.red, display = display.all)

Overview

Grid Bot Z-Score [psyll] computes the MA from chosen type, length and source then derives upper and lower bands offset by stddevs. Grid ranges are set by min and max widths. The indicator draws these levels in a separate pane. Settings modify MA parameters, deviation multiplier, offsets and band widths. Timeframe confirmation and security options are available. It suits range-bound markets such as crypto, forex and equities but requires manual start time setup.

Details

Published by

cullyk on GitHub

Code credit

Copyright, as written in the script's header

Draws

Separate pane below the chart

Markets

Any symbol

Timeframes

Any timeframe

Risk Notes

  • Reads higher-timeframe data with lookahead on, so the history can show signals that were not there in real time

Settings

The inputs you can change from the gear icon on the chart. Defaults are the author's.

SettingTypeDefaultVariable
TypestringSMAma_type
Lengthint500length
Sourcesourceclosesource
Stddevsfloat1.69stddevs
Offsetfloat1offset
Min widthfloat0width_min
Max widthfloat99999width_max
Wait for confirmbooltruetf_confirmation_wait
No repaintbooltruetf_no_repaint_security
Lookaheadboolfalsetf_barmerge_lookahead
Gapsboolfalsetf_barmerge_gaps
TypestringStatictf_type
Show all 15 settings
SettingTypeDefaultVariable
Statictimeframetf_static
Customint1Custom
Candles colorcolorcolor.blackprice_color
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

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
9 stars

This indicator plots an anchored MIDAS support and resistance curve from launch-anchored volume-weighted price on the price chart. It adds two configurable volume-weighted standard-deviation, ATR, or hybrid bands and a topfinder or bottomfinder accelerated exh

Indicator v6 Mean reversionSupport & resistance Repaints
Updated 3 days ago · MIT GitHub repository of MIDAS 2.0 [WavesUnchained]

VWAP Trader NXi

by eddiebelaval
7 stars

VWAP Trader NXi calculates a daily session-anchored Volume Weighted Average Price along with two custom standard deviation bands on the main price chart. It plots the core VWAP, Value Area bands, outer extension zones with background shading, and the previous

Indicator v5 VolumeVolatility & bands
Updated 3 months ago · None stated GitHub repository of VWAP Trader NXi

Calculates and plots a multi-band envelope on the price chart based on mean reversion principles and Keltner Channel concepts. Instead of standard moving averages, it uses advanced filters such as Ehlers SuperSmoother, Butterworth, Gaussian, or traditional ave

Indicator v5 Mean reversionVolatility & bands
Updated 5 months ago · None stated GitHub repository of Mean Reversion Channel - MRI Variant

More Support & resistance 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