Indicator · Pine Script v5 · On the chart

IPDA Standard Deviations

by Ahmed1926· code credited to toodegrees, tradeforopp

An overlay indicator that projects standard deviation levels from interbank price delivery lookback ranges.

View on GitHub

GitHub stars1on the repository
Pine versionv5runs as is
Lines of code233
Settings22inputs
LicenceNone statedfile: MPL-2.0
Last update9 months ago31 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

233 lines of Pine Script v5 from IPDA Deviations.txt, published under MPL-2.0 (file header). Keep the author's credit and licence lines when you reuse it.

IPDA Deviations.txt
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © toodegrees, tradeforopp

//@version=5
indicator( "IPDA Standard Deviations [DexterLab x TFO x toodegrees]"
         , shorttitle= "IPDA Stdev [DexterLab x TFO x toodegrees]"
         , overlay=true
         , max_bars_back=500
         , max_boxes_count=500
         , max_labels_count=500
         , max_lines_count=500)


//#region[User Inputs]
dvs        = input.text_area("0\n1\n-1\n-1.5\n-2\n-2.5\n-4", title="Insert the Deviations you want to plot, one per line:")
label_size =    input.string("Small"                       , title="Label Size"  , options = ['Auto', 'Tiny', 'Small', 'Normal', 'Large', 'Huge'], inline = "lbl")
lbl        =      input.bool(false                         , title="Hide Labels?", inline="lbl")

MLB = input.bool(true , title="Monthly"     , group="Fractal IPDA Lookback", inline="M"), lMTF = input.timeframe("D"  , title="", group="Fractal IPDA Lookback", inline="M"), hMTF = input.timeframe("D"  , title="", group="Fractal IPDA Lookback", inline="M")
WLB = input.bool(true , title="Weekly "     , group="Fractal IPDA Lookback", inline="W"), lWTF = input.timeframe("240", title="", group="Fractal IPDA Lookback", inline="W"), hWTF = input.timeframe("480", title="", group="Fractal IPDA Lookback", inline="W")
DLB = input.bool(true , title="Daily     "  , group="Fractal IPDA Lookback", inline="D"), lDTF = input.timeframe("15" , title="", group="Fractal IPDA Lookback", inline="D"), hDTF = input.timeframe("60" , title="", group="Fractal IPDA Lookback", inline="D")
ILB = input.bool(true , title="Intraday"    , group="Fractal IPDA Lookback", inline="I"), lITF = input.timeframe("1"  , title="", group="Fractal IPDA Lookback", inline="I"), hITF = input.timeframe("5"  , title="", group="Fractal IPDA Lookback", inline="I")

remove = input.bool(false, title="Remove Deviations Once Invalidated?", group="Standard Deviations", tooltip="Once the '1' anchor price line is traded above/below the Deviation will disappear.")
tw3_up = input.bool(true, title="TW3 Up     ", group="Standard Deviations", inline="UP"), tw2_up = input.bool(true, title="TW2 Up    ", group="Standard Deviations", inline="UP"), tw1_up = input.bool(true , title="TW1 Up"  , group="Standard Deviations", inline="UP")
tw3_dw = input.bool(true, title="TW3 Down"   , group="Standard Deviations", inline="DW"), tw2_dw = input.bool(true, title="TW2 Down"  , group="Standard Deviations", inline="DW"), tw1_dw = input.bool(true , title="TW1 Down", group="Standard Deviations", inline="DW")
//#endregion


//#region[Global]
noColor  = color.new(color.white, 100)
midnight = hour(time, "America/New_York")==0 and hour(time[1], "America/New_York")!=0

size(string _size) =>
    size = switch _size
        "Tiny"   => size.tiny
        "Small"  => size.small
        "Normal" => size.normal
        "Large"  => size.large
        "Huge"   => size.huge
    size

tfRange(string LOW, string HIGH)=>
    timeframe.in_seconds(timeframe.period)>=timeframe.in_seconds(LOW) and timeframe.in_seconds(timeframe.period)<=timeframe.in_seconds(HIGH)

var deviations = array.new_float()
string[] chrs = str.split(dvs, "")
if deviations.size()==0 and chrs.size()>0
    var string num = ""
    for i=0 to chrs.size()-1
        c = chrs.get(i)
        if chrs.get(i)=="\n"
            deviations.unshift(str.tonumber(num))
            num := ""
        else
            num += c
    deviations.unshift(str.tonumber(num))
//#endregion


//#region[Functions & Types]
type DexterDev
    string     side
    line[]     lines
    label[]    labels

type TimeWindow
    chart.point h
    chart.point h_stl
    chart.point l
    chart.point l_sth
    line        edge
    DexterDev   up
    DexterDev   dw    

swing_high_point(chart.point prev)=>
    if (high<high[1] and high[1]>high[2]) or (high<=high[1] and high[1]>high[2]) or (high<high[1] and high[1]>=high[2])
        chart.point.from_time(time[1], high[1])
    else
        prev

swing_low_point(chart.point prev)=>
    if (low>low[1] and low[1]<low[2]) or (low>=low[1] and low[1]<low[2]) or (low>low[1] and low[1]<=low[2])
        chart.point.from_time(time[1], low[1])
    else
        prev

method delete(DexterDev DV)=>
    lines  = DV.lines
    if lines.size()>0
        for i=lines.size()-1 to 0
            line.delete(lines.get(i))
        lines.clear()

    labels = DV.labels
    if labels.size()>0
        for i=labels.size()-1 to 0
            label.delete(labels.get(i))
        labels.clear()

method plotDexterDev(TimeWindow TW)=>
    DexterDev stdev_up = DexterDev.new("UP", array.new_line(), array.new_label())
    DexterDev stdev_dw = DexterDev.new("DW", array.new_line(), array.new_label())

    if not na(TW.h) and not na(TW.h_stl)
        rxh = TW.h.time     , lxh = TW.h_stl.time     
        zyh = TW.h_stl.price, yh  = TW.h.price-zyh

        stdev_dw.lines.unshift(line.new(chart.point.from_time(lxh, TW.h.price), TW.h, xloc.bar_time, color=chart.fg_color))
        stdev_dw.labels.unshift(label.new(rxh, TW.h.price, "1", xloc.bar_time, color=noColor, style=label.style_label_left, textcolor= not lbl ? chart.fg_color : noColor, size=size(label_size), text_font_family=font.family_monospace))
        stdev_dw.lines.unshift(line.new(TW.h_stl, chart.point.from_time(rxh, zyh), xloc.bar_time, color=chart.fg_color))
        stdev_dw.labels.unshift(label.new(rxh, zyh, "0", xloc.bar_time, color=noColor, style=label.style_label_left, textcolor= not lbl ? chart.fg_color : noColor, size=size(label_size), text_font_family=font.family_monospace))

        for dv=0 to deviations.size()-1
            dev   = deviations.get(dv)
            price = zyh+(yh*dev)
            stdev_dw.lines.unshift(line.new(lxh, price, rxh, price, xloc.bar_time, color=chart.fg_color))
            stdev_dw.labels.unshift(label.new(rxh, price, str.tostring(dev), xloc.bar_time, color=noColor, style=label.style_label_left, textcolor= not lbl ? chart.fg_color : noColor, size=size(label_size), text_font_family=font.family_monospace))

    if not na(TW.l) and not na(TW.l_sth)
        rxl = TW.l.time     , lxl = TW.l_sth.time
        zyl = TW.l_sth.price, yl  = zyl-TW.l.price

        stdev_up.lines.unshift(line.new(chart.point.from_time(lxl, TW.l.price), TW.l, xloc.bar_time, color=chart.fg_color))
        stdev_up.labels.unshift(label.new(rxl, TW.l.price, "1", xloc.bar_time, color=noColor, style=label.style_label_left, textcolor= not lbl ? chart.fg_color : noColor, size=size(label_size), text_font_family=font.family_monospace))
        stdev_up.lines.unshift(line.new(TW.l_sth, chart.point.from_time(rxl, zyl), xloc.bar_time, color=chart.fg_color))
        stdev_up.labels.unshift(label.new(rxl, zyl, "0", xloc.bar_time, color=noColor, style=label.style_label_left, textcolor= not lbl ? chart.fg_color : noColor, size=size(label_size), text_font_family=font.family_monospace))

        for dv=0 to deviations.size()-1
            dev   = deviations.get(dv)
            price = zyl-(yl*dev)
            stdev_up.lines.unshift(line.new(lxl, price, rxl, price, xloc.bar_time, color=chart.fg_color))
            stdev_up.labels.unshift(label.new(rxl, price, str.tostring(dev), xloc.bar_time, color=noColor, style=label.style_label_left, textcolor= not lbl ? chart.fg_color : noColor, size=size(label_size), text_font_family=font.family_monospace))
        
    TW.up := stdev_up
    TW.dw := stdev_dw
        
method delete(TimeWindow TW)=>
    line.delete(TW.edge)
    TW.up.delete()
    TW.dw.delete()

method removeDev(array<TimeWindow> A)=>
    if A.size()>0
        for i=0 to A.size()-1
            tw=A.get(i)
            if not na(tw.up)
                if tw.up.lines.size()>0
                    if low < tw.up.lines.last().get_y1()
                        tw.up.delete()
            if not na(tw.dw)
                if tw.dw.lines.size()>0
                    if high > tw.dw.lines.last().get_y1()
                        tw.dw.delete()

method hideDev(array<TimeWindow> A, int N, bool UP, bool DW)=>
    if A.size()>N
        tw=A.get(N)
        if not na(tw.up)
            if tw.up.lines.size()>0
                for i=0 to tw.up.lines.size()-1
                    _line=tw.up.lines.get(i)
                    _label=tw.up.labels.get(i)
                    if UP
                        _line.set_color(chart.fg_color)
                        if not lbl
                            _label.set_textcolor(chart.fg_color)
                    else
                        _line.set_color(noColor)
                        _label.set_textcolor(noColor)

        if not na(tw.dw)
            if tw.dw.lines.size()>0
                for i=0 to tw.dw.lines.size()-1
                    _line=tw.dw.lines.get(i)
                    _label=tw.dw.labels.get(i)
                    if DW
                        _line.set_color(chart.fg_color)
                        if not lbl
                            _label.set_textcolor(chart.fg_color)
                    else
                        _line.set_color(noColor)
                        _label.set_textcolor(noColor)
//#endregion


//#region[Find & Plot]
var TWA = array.new<TimeWindow>()
TF = if MLB and tfRange(lMTF, hMTF)
    "M"
else if WLB and tfRange(lWTF, hWTF)
    "W"
else if DLB and tfRange(lDTF, hDTF)
    "D"
else if ILB and tfRange(lITF, hITF)
    "240"

var chart.point prev_h_stl = na
var chart.point prev_l_sth = na
prev_h_stl := swing_low_point(prev_h_stl)
prev_l_sth := swing_high_point(prev_l_sth)

TimeWindow tw = na
if TWA.size()>0
    tw := TWA.first()

if TF=="D"?midnight:timeframe.change(TF)
    if not na(tw)
        tw.plotDexterDev()
        if TWA.size()>3
            TWA.pop().delete()

    TWA.unshift(TimeWindow.new(chart.point.from_time(time, high), na, chart.point.from_time(time, low), na, line.new(time, low, time, high, xloc.bar_time, extend.both, color.new(chart.fg_color, 50), line.style_dotted), na, na))

else if not na(tw)
    if math.max(tw.h.price,high)==high
        tw.h     := chart.point.from_time(time, high)
        tw.h_stl := na(prev_h_stl) ? tw.h_stl : prev_h_stl
    
    if math.min(tw.l.price,low)==low
        tw.l     := chart.point.from_time(time, low)
        tw.l_sth := na(prev_l_sth) ? tw.l_sth : prev_l_sth
//#endregion


//#region[Hide & Remove]
TWA.hideDev(1, tw1_up, tw1_dw)
TWA.hideDev(2, tw2_up, tw2_dw)
TWA.hideDev(3, tw3_up, tw3_dw)

if remove
    TWA.removeDev()
//#endregion

Overview

Monthly, weekly, daily and intraday lookbacks can each be switched on and are applied according to the chart timeframe range set for them. The deviation multiples are typed in as a list, with defaults such as 0, 1, minus 1, minus 1.5 and minus 2. It offers up and down toggles for three time-window groups, label size and hiding, and optional removal of deviations once invalidated. It draws lines and labels on price.

Details

Published by

Ahmed1926 on GitHub

Code credit

toodegrees, tradeforopp, as written in the script's header

Draws

On the price chart

Markets

Any symbol

Timeframes

M15-H1

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
Insert the Deviations you want to plot, one per line:text0 1 -1 -1.5 -2 -2.5 -4dvs
Label SizestringSmalllabel_size
Hide Labels?boolfalselbl
MonthlybooltrueMLB
lMTFtimeframeDlMTF
hMTFtimeframeDhMTF
Weekly booltrueWLB
lWTFtimeframe240lWTF
hWTFtimeframe480hWTF
Daily booltrueDLB
lDTFtimeframe15lDTF
hDTFtimeframe60hDTF
Show all 22 settings
SettingTypeDefaultVariable
IntradaybooltrueILB
lITFtimeframe1lITF
hITFtimeframe5hITF
Remove Deviations Once Invalidated?boolfalseremove
TW3 Up booltruetw3_up
TW2 Up booltruetw2_up
TW1 Upbooltruetw1_up
TW3 Downbooltruetw3_dw
TW2 Downbooltruetw2_dw
TW1 Downbooltruetw1_dw
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

Golden Bullet Strategy

by TradersPost
228 stars

The Golden Bullet Strategy is an overlay signal indicator based on Smart Money Concepts and time-based liquidity models. It identifies liquidity sweeps of a designated reference session range during a specified hunt window. It then confirms Market Structure Sh

Indicator v6 SMC / ICT / price actionSessions & time
Updated 3 months ago · None stated GitHub repository of Golden Bullet Strategy

This indicator detects and draws the first Fair Value Gap (FVG) that forms in each hourly session based on a selected lower timeframe, with specialized handling for Regular Trading Hours (RTH) confluence windows. It draws FVG range boxes, midpoint lines, hourl

Indicator v5 SMC / ICT / price actionSupport & resistance Repaints

This indicator combines six trading tools into a single chart overlay to optimize indicator limits. It calculates Bollinger Bands, projects weekend price boundaries, plots market structure elements like order blocks, breaker blocks, and MSB lines, marks New Yo

Indicator v6 Support & resistanceSMC / ICT / price action Repaints
19 stars

This indicator highlights Inner Circle Trader (ICT) killzones and key session pivot points directly on the price chart. It projects shaded boxes for specific trading sessions, including Asia, London, NY AM, NY Lunch, and NY PM, to help traders identify high-li

Indicator v5 SMC / ICT / price actionSessions & time
Updated 3 years ago · MIT GitHub repository of ICT Killzones & Pivots

Bandz Session Ranges + ORG + Opening Prices plots trading session ranges, killzones, opening RTH gaps, standard deviation projections, and key opening prices directly on the price chart. It calculates gap ranges based on prior regular trading hours close sourc

Indicator v6 Sessions & timeSupport & resistance
Updated 2 weeks ago · MPL-2.0 GitHub repository of Bandz Session Ranges + ORG + Opening Prices

More SMC / ICT 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