Multiple Frequency Volatility Correlation
// 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)
