Interval Volatility Bands [DW]
"Interval Volatility Bands [DW]" by DonovanWall, MPL-2.0. Ported to FloScript by FloSignals; modifications under MPL-2.0. Original: Interval Volatility Bands [DW] (v6.0), read 2026-10-12T15:59:50.178Z; source language v4.
Licence: Mozilla Public License 2.0 (MPL-2.0) — full text. The source is published with it, modifications included, under the same licence.
Interval Volatility Bands [DW] by DonovanWall, ported from Pine v4. Overlay indicator with 13 plots, 12 fills, bar/background colouring and 17 inputs.
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © DonovanWall
//██████╗ ██╗ ██╗
//██╔══██╗██║ ██║
//██║ ██║██║ █╗ ██║
//██║ ██║██║███╗██║
//██████╔╝╚███╔███╔╝
//╚═════╝ ╚══╝╚══╝
// ------------------------------------------------------------------------------------------------
// Original author: DonovanWall
// Original title: Interval Volatility Bands [DW]
// Licence: MPL-2.0 (the header above is the original notice, kept verbatim)
// Pine version: 4
// Fetched: 2026-10-12
// Ported to FloScript by FloSignals; modifications under MPL-2.0.
// Converter: @flosignals/floscript 0.1.0, strict mode, score 100/100
// ------------------------------------------------------------------------------------------------
//@floscript=1
//@version=5
// Converted by the FloScript converter from a Pine-compatible v4 source.
indicator(title="Interval Volatility Bands [DW]", shorttitle="IVB [DW]", overlay=true)
//by Donovan Wall
//This is an experimental study that utilizes Volume Weighted Average Price or Time Weighted Average Price calculations, Bollinger Bands, and Fibonacci numbers to estimate volatility over a specified interval.
//First, the basis is calculated by selecting:
// -VWAP, which has the option to be calculated using real volume or tick volume
// -TWAP, which has the option to be calculated using the standard method or exponential method
//Next, standard deviation from the basis is calculated and multiplied by a specified expansion coefficient. The result is then added to and subtracted from the basis to calculate the high and low bands.
//There are three band calculation methods to chosse from in this script:
// -Standard, which uses the default calculations
// -Average, which takes a cumulative average of standard deviation
// -Hybrid, which takes the maximum of the standard and average standard deviation methods
//Lastly, the high and low band ranges are multiplied by Fibonacci Percentages 23.6 - 78.6.
//A custom color scheme with eight default presets to choose from is included.
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Updates:
//I altered the inputs for a simpler experience. Calculation method, VWAP volume type, TWAP smoothing type, band calculation method, and color scheme are all controlled with easy to use dropdown menus.
//An option to use automatic interval settings is now available. You can still choose a custom interval by deselecting this option.
//Double Exponential Time Weighted Average Price (DETWAP) has been added to the script. Simply select "Double Exponential" from the TWAP Smoothing Type menu to enable it.
//I also added a couple new color schemes to the mix, Prism 1 and Prism 2, which are multicolored themes for those who like a bit of variety in their colors.
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Updates:
//In the midst of migrating the script from pine v2 to v3, I forgot that the lookahead settings need to be changed on security functions.
//v3 by default turns lookahead off, resulting in the security function tracking current resolution data on the current bar, and alternate resolution data in the past.
//Lookahead has been turned back on so the alternate resolution results reflect on the current bar.
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Updates:
//Fixed a repainting issue in the script by changing the interval renewal condition.
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Updates:
// -> Migrated to v4.
// -> Reorganized script structure.
// -> Reduced clutter for quicker compile.
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Updates:
// - Rebuilt the weighted average price functions using Pine's new array data structures.
// - Condensed interval calculation options into a singular dropdown tab with 4 options to choose from:
// -> Automatic Segmented - Automatically chooses a timeframe for a segmented interval.
// -> Custom Segmented - Uses a user defined interval based on an input resolution.
// -> Cumulative - Uses the entire chart to cumulatively calculate.
// -> Time Anchored Cumulative - Cumulatively calculates from a user defined point in time. If the time is before the time of the first bar, this behaves the same as the cumulative option.
// - Reorganized the GUI.
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Functions
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Interval Renewal Function
newbar(T) =>
t = time(T)
newbar = na(t[1]) and not na(t) or t[1] < t ? 1 : 0
newbar
//VWAP Function
VWAP(x, T, v_type, c_mode, anch, stamp) =>
tick = syminfo.mintick
rng = close - open
tickrng = tick
tickrng := math.abs(rng) < tick ? nz(tickrng[1]) : rng
tickvol = math.abs(tickrng) / tick
vol = v_type == "Default" ? nz(volume, tickvol) : tickvol
pv = x * vol
var v_vals = array.new_float(0)
var pv_vals = array.new_float(0)
newint = c_mode or anch ? 0 : newbar(T)
if newint
array.clear(v_vals)
array.clear(pv_vals)
if time >= (anch ? stamp : 0)
array.push(v_vals, vol)
array.push(pv_vals, pv)
VWAP = array.sum(pv_vals) / array.sum(v_vals)
VWAP
//TWAP Function
TWAP(x, T, c_mode, anch, stamp) =>
var p_vals = array.new_float(0)
newint = c_mode or anch ? 0 : newbar(T)
if newint
array.clear(p_vals)
if time >= (anch ? stamp : 0)
array.push(p_vals, x)
TWAP = array.sum(p_vals) / array.size(p_vals)
TWAP
//ETWAP Function
ETWAP(x, T, c_mode, anch, stamp) =>
var wap_vals = array.new_float(2, 0.0)
var p_vals = array.new_float(0)
newint = c_mode or anch ? 0 : newbar(T)
if newint
array.clear(p_vals)
if time >= (anch ? stamp : 0)
array.push(p_vals, x)
array.set(wap_vals, 1, array.get(wap_vals, 0))
array.set(wap_vals, 0, array.get(wap_vals, 1) + (x - array.get(wap_vals, 1)) * (2 / (array.size(p_vals) + 1)))
ETWAP = array.get(wap_vals, 0)
ETWAP
//DETWAP Function
DETWAP(x, T, c_mode, anch, stamp) =>
2 * ETWAP(x, T, c_mode, anch, stamp) - ETWAP(ETWAP(x, T, c_mode, anch, stamp), T, c_mode, anch, stamp)
//WAP Selection Function
WAP(x, T, calc, t_type, v_type, c_mode, anch, stamp) =>
float WAP = na
if calc == "VWAP"
WAP := VWAP(x, T, v_type, c_mode, anch, stamp)
if calc == "TWAP"
if t_type == "Simple"
WAP := TWAP(x, T, c_mode, anch, stamp)
if t_type == "Exponential"
WAP := ETWAP(x, T, c_mode, anch, stamp)
if t_type == "Double Exponential"
WAP := DETWAP(x, T, c_mode, anch, stamp)
WAP
//Custom Standard Deviation Function
STDEV(x, T, calc, t_type, v_type, c_mode, anch, stamp) =>
devsq = math.pow(x - WAP(x, T, calc, t_type, v_type, c_mode, anch, stamp), 2)
vari = WAP(devsq, T, calc, t_type, v_type, c_mode, anch, stamp)
STDEV = math.sqrt(vari)
STDEV
//Cumulative Average Function
cmean(x) =>
var p_vals = array.new_float(0)
array.push(p_vals, x)
cmean = array.avg(p_vals)
cmean
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Inputs
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Interval Type
inter_type = input.string(defval="Automatic Segmented", options=["Automatic Segmented", "Custom Segmented", "Cumulative", "Time Anchored Cumulative"], title="Interval Type")
//Custom Segmented Interval
rescustom = input(defval="D", title="Custom Segmented Interval")
//Time Anchoring Inputs
auto_tz = input(defval=true, title="Use Chart Timezone")
cust_tz = input(defval="GMT+0", title="Timezone")
anch_year = input.int(defval=1970, minval=1970, title="Time Anchor Year")
anch_month = input.int(defval=1, minval=1, maxval=12, title="Time Anchor Month")
anch_day = input.int(defval=1, minval=1, maxval=31, title="Time Anchor Day")
anch_hour = input.int(defval=0, minval=0, maxval=23, title="Time Anchor Hour")
anch_minute = input.int(defval=0, minval=0, maxval=59, title="Time Anchor Minute")
anch_second = input.int(defval=0, minval=0, maxval=59, title="Time Anchor Second ═══════════════════")
//Source
src = input(defval=close, title="Input Source Price")
//Calculation Method
cmethod = input.string(defval="VWAP", options=["VWAP", "TWAP"], title="Calculation Method")
//Volume Type
vol_type = input.string(defval="Default", options=["Default", "Tick"], title="VWAP Volume Type")
//TWAP Smoothing Type
twap_type = input.string(defval="Simple", options=["Simple", "Exponential", "Double Exponential"], title="TWAP Smoothing Type")
//Band Calculation Method
bandmode = input.string(defval="Standard", options=["Standard", "Cumulative Average", "Hybrid"], title="Band Calculation Method")
//Expansion Coefficient
emult = input.float(defval=2.0, minval=0, title="Expansion Coefficient ═══════════════════")
//Color Scheme Selection
colmode = input.string(defval="GR Full", options=["GR Full", "GR Skeleton", "BP Full", "BP Skeleton", "YO Full", "YO Skeleton", "WG Full", "WG Skeleton", "Prism 1", "Prism 2"], title="Color Scheme Selection (10 Available Presets)")
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Definitions
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Auto Resolution
inter = timeframe.isintraday ? timeframe.multiplier : timeframe.isdaily ? timeframe.multiplier * 1440 : timeframe.isweekly ? timeframe.multiplier * 10080 : timeframe.multiplier
autores = inter < 5 ? "360" : inter >= 5 and inter < 10 ? "720" : inter >= 10 and inter < 30 ? "D" : inter >= 30 and inter < 240 ? "W" : inter >= 240 and inter < 1440 ? "M" : "12M"
res = inter_type == "Automatic Segmented" ? autores : rescustom
//Time Anchor
anch_tz = auto_tz ? syminfo.timezone : cust_tz
time_stamp = timestamp(anch_tz, anch_year, anch_month, anch_day, anch_hour, anch_minute, anch_second)
//Basis Line
basis = WAP(src, res, cmethod, twap_type, vol_type, inter_type == "Cumulative", inter_type == "Time Anchored Cumulative", time_stamp)
//Standard Deviation
stdev = STDEV(src, res, cmethod, twap_type, vol_type, inter_type == "Cumulative", inter_type == "Time Anchored Cumulative", time_stamp)
//Cumulative Average Standard Deviation
cad = cmean(stdev)
//Cumulative Average Standard Deviation Toggle
xdev = bandmode == "Cumulative Average" ? cad : bandmode == "Standard" ? stdev : math.max(cad, stdev)
//Bands
hband = basis + xdev * emult
h786 = basis + xdev * emult * 0.786
h618 = basis + xdev * emult * 0.618
h50 = basis + xdev * emult * 0.5
h382 = basis + xdev * emult * 0.382
h236 = basis + xdev * emult * 0.236
l236 = basis - xdev * emult * 0.236
l382 = basis - xdev * emult * 0.382
l50 = basis - xdev * emult * 0.5
l618 = basis - xdev * emult * 0.618
l786 = basis - xdev * emult * 0.786
lband = basis - xdev * emult
//Color Schemes
skeleton = colmode == "GR Skeleton" or colmode == "BP Skeleton" or colmode == "YO Skeleton" or colmode == "WG Skeleton" ? 1 : 0
ubasiscolor1 = colmode == "GR Full" or colmode == "GR Skeleton" ? #00ff00 : colmode == "BP Full" or colmode == "BP Skeleton" ? #00ffff : colmode == "YO Full" or colmode == "YO Skeleton" ? #ffff00 : #ffffff
ubasiscolor2 = colmode == "GR Full" or colmode == "GR Skeleton" ? #00cc00 : colmode == "BP Full" or colmode == "BP Skeleton" ? #008080 : colmode == "YO Full" or colmode == "YO Skeleton" ? #DAA520 : #F5F5F5
dbasiscolor1 = colmode == "GR Full" or colmode == "GR Skeleton" ? #ff0000 : colmode == "BP Full" or colmode == "BP Skeleton" ? #ff00ff : colmode == "YO Full" or colmode == "YO Skeleton" ? #FFA500 : #FFFAFA
dbasiscolor2 = colmode == "GR Full" or colmode == "GR Skeleton" ? #800000 : colmode == "BP Full" or colmode == "BP Skeleton" ? #8B008B : colmode == "YO Full" or colmode == "YO Skeleton" ? #D2691E : #FFE4E1
ucolor1 = colmode == "Prism 1" ? #ff0000 : colmode == "Prism 2" ? #ff00ff : ubasiscolor1
ucolor2 = colmode == "Prism 1" ? #FFA500 : colmode == "Prism 2" ? #00ffff : skeleton ? #000000 : ubasiscolor1
ucolor3 = colmode == "Prism 1" ? #ffff00 : colmode == "Prism 2" ? #00ff00 : skeleton ? #000000 : ubasiscolor1
ucolor4 = colmode == "Prism 1" ? #00ff00 : colmode == "Prism 2" ? #ffff00 : skeleton ? #000000 : ubasiscolor1
ucolor5 = colmode == "Prism 1" ? #00ffff : colmode == "Prism 2" ? #FFA500 : skeleton ? #000000 : ubasiscolor1
ucolor6 = colmode == "Prism 1" ? #ff00ff : colmode == "Prism 2" ? #ff0000 : ubasiscolor1
dcolor1 = colmode == "Prism 1" ? #ff0000 : colmode == "Prism 2" ? #ff00ff : dbasiscolor1
dcolor2 = colmode == "Prism 1" ? #FFA500 : colmode == "Prism 2" ? #00ffff : skeleton ? #000000 : dbasiscolor1
dcolor3 = colmode == "Prism 1" ? #ffff00 : colmode == "Prism 2" ? #00ff00 : skeleton ? #000000 : dbasiscolor1
dcolor4 = colmode == "Prism 1" ? #00ff00 : colmode == "Prism 2" ? #ffff00 : skeleton ? #000000 : dbasiscolor1
dcolor5 = colmode == "Prism 1" ? #00ffff : colmode == "Prism 2" ? #FFA500 : skeleton ? #000000 : dbasiscolor1
dcolor6 = colmode == "Prism 1" ? #ff00ff : colmode == "Prism 2" ? #ff0000 : dbasiscolor1
basiscolor1 = src > src[1] and src > basis ? ubasiscolor1 : src < src[1] and src > basis ? ubasiscolor2 : src < src[1] and src < basis ? dbasiscolor1 : src > src[1] and src < basis ? dbasiscolor2 : #000000
basiscolor = colmode == "Prism 1" or colmode == "Prism 2" ? (src > basis ? #90EE90 : src < basis ? #F08080 : #808080) : basiscolor1
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Outputs
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Basis Plot
basisplot = plot(basis, color=color.new(basiscolor, 0), linewidth=1, title="Basis Level")
//Band Plots
hbandplot = plot(hband, color=color.new(ucolor1, 100), linewidth=1, title="High Band")
h786plot = plot(h786, color=color.new(ucolor1, 100), linewidth=1, title="78.6% High Band")
h618plot = plot(h618, color=color.new(ucolor2, 100), linewidth=1, title="61.8% High Band")
h50plot = plot(h50, color=color.new(ucolor3, 100), linewidth=1, title="50% High Band")
h382plot = plot(h382, color=color.new(ucolor4, 100), linewidth=1, title="38.2% High Band")
h236plot = plot(h236, color=color.new(ucolor5, 100), linewidth=1, title="23.6% High Band")
l236plot = plot(l236, color=color.new(dcolor5, 100), linewidth=1, title="23.6% Low Band")
l382plot = plot(l382, color=color.new(dcolor4, 100), linewidth=1, title="38.2% Low Band")
l50plot = plot(l50, color=color.new(dcolor3, 100), linewidth=1, title="50% Low Band")
l618plot = plot(l618, color=color.new(dcolor2, 100), linewidth=1, title="61.8% Low Band")
l786plot = plot(l786, color=color.new(dcolor1, 100), linewidth=1, title="78.6% Low Band")
lbandplot = plot(lband, color=color.new(dcolor1, 100), linewidth=1, title="Low Band")
//Band Fills
fill(h786plot, hbandplot, color=color.new(ucolor1, 70), title="High Range 6")
fill(h618plot, h786plot, color=color.new(ucolor2, 90), title="High Range 5")
fill(h50plot, h618plot, color=color.new(ucolor3, 75), title="High Range 4")
fill(h382plot, h50plot, color=color.new(ucolor4, 80), title="High Range 3")
fill(h236plot, h382plot, color=color.new(ucolor5, 85), title="High Range 2")
fill(basisplot, h236plot, color=color.new(ucolor6, 90), title="High Range 1")
fill(basisplot, l236plot, color=color.new(dcolor6, 90), title="Low Range 1")
fill(l236plot, l382plot, color=color.new(dcolor5, 85), title="Low Range 2")
fill(l382plot, l50plot, color=color.new(dcolor4, 80), title="Low Range 3")
fill(l50plot, l618plot, color=color.new(dcolor3, 75), title="Low Range 4")
fill(l618plot, l786plot, color=color.new(dcolor2, 90), title="Low Range 5")
fill(l786plot, lbandplot, color=color.new(dcolor1, 70), title="Low Range 6")
//Bar Color
barcolor(basiscolor)
This file is under the Mozilla Public License 2.0; it is a port of the original by DonovanWall, with the original licence header kept and the changes made for FloScript noted in the file.
- v2
Library refresh 2026-10-14
- v1
Library refresh 2026-10-12
Disclaimer. Scripts are written and published by members, or ported by FloSignals from open-source originals, and are their authors' own work and opinion. FloSignals does not review them for correctness and nothing in a script is financial advice or a recommendation to buy or sell anything — read the Risk Disclaimer. Posting here is under the Community Rules; a script that is not the poster's to post can be reported as the Copyright & Takedowns page says.

Comments (0)
No comments yet. Members can leave one.