Indicator · Pine Script v5 · Own pane

Multiple Frequency Volatility Correlation

by regalouisei· code credited to RicardoSantos

Multiple Frequency Volatility Correlation measures the relationship between price standard deviation and volume standard deviation across window lengths ranging from 2 to 512 bars.

View on GitHub

GitHub stars2on the repository
Pine versionv5runs as is
Lines of code159
Settings2inputs
LicenceNone statedfile: MPL-2.0
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

159 lines of Pine Script v5 from pinescript/editors_picks/multiple-frequency-volatility-correlation.pine, published under MPL-2.0 (file header). Keep the author's credit and licence lines when you reuse it.

multiple-frequency-volatility-correlation.pine
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © RicardoSantos

//@version=5
indicator(title='Multiple Frequency Volatility Correlation', shorttitle='MFVC', overlay=false)

// description:
//  This is a complex indicator that looks to provide some insight 
//  into the correlation between volume and price volatility.
//  Rising volatility is depicted with the color green while falling
//  volatility is depicted with purple.
//  Lightness of the color is used to depict the length of the window 
//  used, darker == shorter in the 0 -> 512 window range.
//  

import RicardoSantos/ColorExtension/4 as colExt

// @function determines color and correlation level.
vc (window, smoothing) => 
    float _price = ta.stdev(close, window)
    float _vol   = ta.stdev(volume, window)
    float _cor   = ta.correlation(_price, _vol, smoothing)
    float _vol_filter = ta.rising(_price, 1) ? 100 : 300 // green : purple
    float _win_filter = 25 + (window / 512) * 40 // higher value, lighter color
    color _col   = colExt.hsl(_vol_filter, 60, _win_filter, 20)
    [_col, _cor]
//
int smoothing = input.int(10)

[c002, v002] = vc(  2, smoothing)
[c003, v003] = vc(  3, smoothing)
[c004, v004] = vc(  4, smoothing)
[c006, v006] = vc(  6, smoothing)
[c008, v008] = vc(  8, smoothing)
[c012, v012] = vc( 12, smoothing)
[c016, v016] = vc( 16, smoothing)
[c024, v024] = vc( 24, smoothing)
[c032, v032] = vc( 32, smoothing)
[c048, v048] = vc( 48, smoothing)
[c064, v064] = vc( 64, smoothing)
[c096, v096] = vc( 96, smoothing)
[c128, v128] = vc(128, smoothing)
[c192, v192] = vc(192, smoothing)
[c256, v256] = vc(256, smoothing)
[c384, v384] = vc(384, smoothing)
[c512, v512] = vc(512, smoothing)

array<float> data = array.from(
      v002, v003, v004, v006, v008, v012, v016, v024, v032, 
      v048, v064, v096, v128, v192, v256, v384, v512
      )

float min = array.min(data)
float max = array.max(data)
float avg = array.avg(data)

plot(series=v002, title='V002', color=c002, style=plot.style_circles)
plot(series=v003, title='V003', color=c003, style=plot.style_circles)
plot(series=v004, title='V004', color=c004, style=plot.style_circles)
plot(series=v006, title='V006', color=c006, style=plot.style_circles)
plot(series=v008, title='V008', color=c008, style=plot.style_circles)
plot(series=v012, title='V012', color=c012, style=plot.style_circles)
plot(series=v016, title='V016', color=c016, style=plot.style_circles)
plot(series=v024, title='V024', color=c024, style=plot.style_circles)
plot(series=v032, title='V032', color=c032, style=plot.style_circles)
plot(series=v048, title='V048', color=c048, style=plot.style_circles)
plot(series=v064, title='V064', color=c064, style=plot.style_circles)
plot(series=v096, title='V096', color=c096, style=plot.style_circles)
plot(series=v128, title='V128', color=c128, style=plot.style_circles)
plot(series=v192, title='V192', color=c192, style=plot.style_circles)
plot(series=v256, title='V256', color=c256, style=plot.style_circles)
plot(series=v384, title='V384', color=c384, style=plot.style_circles)
plot(series=v512, title='V512', color=c512, style=plot.style_circles)

plot(series=min, title='min', color=color.rgb(120, 123, 134, 40))
plot(series=max, title='max', color=color.rgb(120, 123, 134, 40))
plot(series=avg, title='avg', color=color.teal)

//
array<int> hist_values = array.new<int>(20, 0)
var array<box> hist_boxes = array.new<box>(20)
var array<box> hist_boxes1 = array.new<box>(20)

if barstate.isfirst
    for _i = 0 to 19
        array.set(hist_boxes, _i, box.new(0, 0.0, 0, 0.0))
        array.set(hist_boxes1, _i, box.new(0, 0.0, 0, 0.0, bgcolor=color.rgb(243, 159, 33, 53)))

for _e in data
    int _lvl = math.round(((1 + _e) / 2.0) * 19)
    array.set(hist_values, _lvl, array.get(hist_values, _lvl) + 1)


int __sumlength = input.int(10)

int s00 = int(math.sum(array.get(hist_values, 00), __sumlength))
int s01 = int(math.sum(array.get(hist_values, 01), __sumlength))
int s02 = int(math.sum(array.get(hist_values, 02), __sumlength))
int s03 = int(math.sum(array.get(hist_values, 03), __sumlength))
int s04 = int(math.sum(array.get(hist_values, 04), __sumlength))
int s05 = int(math.sum(array.get(hist_values, 05), __sumlength))
int s06 = int(math.sum(array.get(hist_values, 06), __sumlength))
int s07 = int(math.sum(array.get(hist_values, 07), __sumlength))
int s08 = int(math.sum(array.get(hist_values, 08), __sumlength))
int s09 = int(math.sum(array.get(hist_values, 09), __sumlength))
int s10 = int(math.sum(array.get(hist_values, 10), __sumlength))
int s11 = int(math.sum(array.get(hist_values, 11), __sumlength))
int s12 = int(math.sum(array.get(hist_values, 12), __sumlength))
int s13 = int(math.sum(array.get(hist_values, 13), __sumlength))
int s14 = int(math.sum(array.get(hist_values, 14), __sumlength))
int s15 = int(math.sum(array.get(hist_values, 15), __sumlength))
int s16 = int(math.sum(array.get(hist_values, 16), __sumlength))
int s17 = int(math.sum(array.get(hist_values, 17), __sumlength))
int s18 = int(math.sum(array.get(hist_values, 18), __sumlength))
int s19 = int(math.sum(array.get(hist_values, 19), __sumlength))
int stotal = s00 + s01 + s02 + s03 + s04 + s05 + s06 + s07 + s08 + s09 + s10 + s11 + s12 + s13 + s14 + s15 + s16 + s17 + s18 + s19
get_sum(int idx)=>
    int _a = switch idx
        00 => s00
        01 => s01
        02 => s02
        03 => s03
        04 => s04
        05 => s05
        06 => s06
        07 => s07
        08 => s08
        09 => s09
        10 => s10
        11 => s11
        12 => s12
        13 => s13
        14 => s14
        15 => s15
        16 => s16
        17 => s17
        18 => s18
        19 => s19
    _a
//
for _i = 0  to 19
    box _box = array.get(hist_boxes, _i)
    float _pos = -1.0 + (_i / 10.0)
    int _nhits = array.get(hist_values, _i)
    int _nhits1 = get_sum(_i)
    int _nhits1_perc = 100 * (_nhits1 / stotal)
    box.set_lefttop(    _box, 1 + bar_index         , _pos + 0.1)
    box.set_rightbottom(_box, 1 + bar_index + _nhits, _pos      )
    box.set_text(       _box, str.format('{0} ( {1}%)', str.tostring(_nhits, '0'), str.tostring(100*(_nhits / 17),'0')))

    box _box1 = array.get(hist_boxes1, _i)
    box.set_lefttop(    _box1, 1 + bar_index               , _pos + 0.1)
    box.set_rightbottom(_box1, int(1 + bar_index + _nhits1_perc), _pos      )
    box.set_text(       _box1, str.format('{0} ( {1}%)', str.tostring(_nhits1, '0'), str.tostring(_nhits1_perc,'0')))

var label_top = label.new(x=bar_index, y= 1.0, color=color.silver, style=label.style_label_lower_left, text='high synchronicity', tooltip='there is high connection between price returns and volume change.\ngreen color: rising momentum.\npurple color: falling momentum.', size=size.small)
var label_bot = label.new(x=bar_index, y=-1.0, color=color.silver, style=label.style_label_upper_left, text='low synchronicity' , tooltip='there is low connection between price returns and volume change.\ngreen color: rising momentum.\npurple color: falling momentum.' , size=size.small)
label.set_x(label_top, bar_index)
label.set_x(label_bot, bar_index)

Overview

Multiple Frequency Volatility Correlation plots individual correlation values as colored circles in a separate indicator pane alongside lines representing the minimum, maximum, and average correlations across all frequencies. Color hues indicate whether price volatility is rising or falling, while lightness corresponds to the window length. Users can adjust the correlation smoothing length parameter.

Details

Published by

regalouisei on GitHub

Code credit

RicardoSantos, 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
smoothingint10smoothing
__sumlengthint10__sumlength
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

This indicator plots a Supertrend-based trend-following setup in a separate pane and skips conditions it treats as a sideways market. A volatility range is built from an ATR value, with RMA, SMA, EMA, or WMA smoothing, or from a fixed point distance. Optional

Indicator v5 TrendVolatility & bands
Updated 1 year ago · MPL-2.0 GitHub repository of Trend Following Setup - Sideways Market Skipper
114 stars

This indicator standardizes price inputs using z-score normalization before calculating a relative strength index (RSI). It generates trade signals when standardized price components cross over or under the standardized RSI feature. Signals can be filtered by

Indicator v4 Oscillators & momentumVolatility & bands Repaints
Updated 1 year ago · None stated GitHub repository of Preprosessed & Standardized RSI
99 stars

This script calculates Bill Williams' Market Facilitation Index (BW MFI) to evaluate price movement efficiency relative to trading volume. It computes the range between the high and low prices divided by volume for each bar, returning zero when volume is zero.

Indicator v6 VolumeVolatility & bands
Updated 4 weeks ago · Apache-2.0 GitHub repository of Market Facilitation Index (MARKETFI)

PPO ATR Bands

by cryptorife
75 stars

PPO ATR Bands plots a percentage price oscillator in a separate pane. It compares a Hull average of typical price with a volume-weighted exponential average of Parabolic SAR, then scales three true-range bands around the slow average into matching oscillator l

Indicator v4 Oscillators & momentumMoving averages
Updated 3 years ago · GPL-3.0 GitHub repository of PPO ATR Bands

This indicator combines Chaikin Money Flow (CMF), a SuperTrend baseline, and an Average True Range (ATR) calculation inside a separate sub-pane. It calculates a standard 20-period CMF plotted as a line and colored histogram columns around a zero baseline, trac

Indicator v6 TrendVolume
Updated 6 months ago · Apache-2.0 GitHub repository of Institutional View: CMF & SuperTrend

More Volatility & bands 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