Extreme Volume Support Resistance Levels
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © tarasenko_

//@version=5
indicator("Extreme Volume Support Resistance Levels", shorttitle = "EVSR Levels", overlay = 1)


// Inputs
use_mtf = input(false, "Use MTF?", tooltip = "MTF - Multi Timeframe - option for using data from different timeframes on your current timeframe.", group = "MTF")
dtf = input.string('3', "Timeframe", options = ['1', '3', '5', '15', '30', '45', '60', '240', '480', '1440'], group = "MTF")
use_custom_tf = input(false, "Use custom timeframe?", group = "MTF")
custom_tf = input(3, "Custom Timeframe", tooltip = "Enter timeframe in minutes: 60 - 1H, 240 - 4H and etc.", group = "MTF")
p = input.int(400, "Lookback", maxval = 2000, minval = 100, group = "Main Settings")
vp = input(200, "Volume Threshold Period", group = "Main Settings")
vm = input.float(3, "Volume Threshold Multiplier", group = "Main Settings")
boxes_to_show = input(2, "Number of zones to show", group = "Main Settings")
show_db = input(true, "Show TF Dashboard?", tooltip = "Shows chosen MTF and your current timeframe, so you could see what timeframes you are using at the moment.", group = "Dashboard")
db_board_thickness = input(2, "DB Board Thickness", group = "Dashboard")
db_frame_width = input.int(1, "DB Frame Width", group = "Dashboard")
box_extend_type = input.string("Both", "Zones' Extend", options = ["Both", "Right", "Left"], group = "Extra")
box_extend = box_extend_type == "Both" ? extend.both : box_extend_type == "Right" ? extend.right : extend.left
box_filling = input(true, "Use color filling of zones?", group = "Extra")


// Functions
// Drawing zones
draw_sr_zones(o, h, l, c) =>
    upper_box = box.new(bar_index - 1, h, bar_index, c > o ? c : o, close > h ? #00ff0050 : #ff000050, 2, line.style_solid, box_extend, xloc.bar_index, box_filling ? (close > h ? #00ff0020 : #ff000020) : na)
    lower_box = box.new(bar_index - 1, c > o ? o : c, bar_index, l, close > l ? #00ff0050 : #ff000050, 2, line.style_solid, box_extend, xloc.bar_index, box_filling ? (close > l ? #00ff0020 : #ff000020) : na)


// Necessary global variables
tf = use_mtf ? (use_custom_tf ? str.tostring(custom_tf) : dtf) : timeframe.period   // Timeframe
O = request.security(syminfo.tickerid, tf, open[1])                                 // MTF previous open
H = request.security(syminfo.tickerid, tf, high[1])                                 // MTF previous high
L = request.security(syminfo.tickerid, tf, low[1])                                  // MTF previous low
C = request.security(syminfo.tickerid, tf, close[1])                                // MTF previous close
 

// Calculations
v  = request.security(syminfo.tickerid, tf, volume[1])                    // Requesting MTF volume
vl = request.security(syminfo.tickerid, tf, ta.ema(v, vp))                // Requesting MTF smoothed volume 
vt = request.security(syminfo.tickerid, tf, vl * vm)                      // Requesting MTF "lifted" smoothed volume    


// Plottings
if ta.crossover(v, vt)                                                                  
    box_array = box.all                                                                 // Array of all plotted boxes. Veru useful deleting boxes themselves
    while array.size(box_array) > 0 and array.size(box_array) >= 2 * boxes_to_show      // Cleaning already existing boxes in order to give space for new boxes
        box.delete(array.shift(box_array))                                              // Cleaning first line in box array = 1st lastest drawn zone
        box.delete(array.shift(box_array))                                              // Cleaning second line in box array = 2nd lastest drawn zone
    draw_sr_zones(O, H, L, C)                                                           // Calling main function to draw the zones


if show_db                                                                // Enabling/Disabling TF Dashboard, next group of lines is just customization
    table db = table.new(position.top_right, 2, 3, color.rgb(30, 32, 38, 50), color.rgb(0, 0, 0), db_frame_width, color.rgb(0, 0, 0), db_board_thickness)
    table.cell(db, 0, 0, "MTF", text_color = color.white, bgcolor = color.black, tooltip = "MTF that you've chosen.")
    table.cell(db, 1, 0, str.tostring(tf), text_color = color.white, text_font_family = font.family_monospace)
    table.cell(db, 0, 1, "Current\ntimeframe", text_color = color.white, bgcolor = color.black, tooltip = "Your current timeframe.")
    table.cell(db, 1, 1, timeframe.period, text_color = color.white, text_font_family = font.family_monospace)
    table.cell(db, 0, 2, "Zones found", text_color = color.white, bgcolor = color.black, tooltip = "Number of S/R zones, found by algorithm. If it equals 0, then there is no zones, try playing with other settings.")
    table.cell(db, 1, 2, str.tostring(array.size(box.all)), text_color = color.white, text_font_family = font.family_monospace, bgcolor = array.size(box.all) == 0 ? #ff000050 : color.rgb(30, 32, 38, 50))
