OMXS30 Volume
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Ohellas

// This indicator summarizes the volume for all stock in the OMXS30 index. Wait until the candle closes before reading the volume.

//If you want to hide the volume until close of candle you can replace the request.security with the f_secureSecurity function defined below
// Each row for each stock would look like this for example f_secureSecurity("OMXSTO:ABB",timeframe,volume)
//Or if you know how to fix this issue please let me know

//@version=5
indicator("OMXS30 Volume", overlay=false)

showMA =                    input(false,  title="Show Volume Moving Average")
showVSA =                      input(false,  title="Show Volume Spread Analysis")
showVolumeChange =                      input(false,  title="Color of bar indicates if volume increases or decreases, must disable VSA to work")
timefilter =                input(true, title="Enable timefilter to remove first and last bar")
int lengthVolumeMA =        input(20,    title="Length of MA applied on Volume")
float ratioUltraVolume =      input(2.2,   title="Ultra High Volume Ratio")
float ratioVeryHighVolume =   input(1.8,   title="Very High Volume Ratio")
float ratioHighVolume =       input(1.2,   title="High Volume Ratio")
float ratioNormalVolume =     input(0.8,   title="Normal Volume Ratio")
float ratioLowVolume =        input(0.4,   title="Low Volume Ratio")
float ratioVeryLowVolume =    input(0.4,   title="Very Low Volume Ratio")


timeframe=timeframe.period

f_secureSecurity(_symbol, _res, _src) => request.security(_symbol, _res, _src[1], lookahead = barmerge.lookahead_on)

totvol = request.security("OMXSTO:ABB",timeframe,volume) + 
         request.security("OMXSTO:ALFA",timeframe,volume) + 
         request.security("OMXSTO:ALIV_SDB",timeframe,volume) +
         request.security("OMXSTO:ASSA_B",timeframe,volume) +   
         request.security("OMXSTO:ATCO_A",timeframe,volume) +
         request.security("OMXSTO:ATCO_B",timeframe,volume) +
         request.security("OMXSTO:AZN",timeframe,volume) + 
         request.security("OMXSTO:BOL",timeframe,volume) + 
         request.security("OMXSTO:ELUX_B",timeframe,volume) + 
         request.security("OMXSTO:ERIC_B",timeframe,volume) +
         request.security("OMXSTO:ESSITY_B",timeframe,volume) +
         request.security("OMXSTO:EVO",timeframe,volume) + 
         request.security("OMXSTO:GETI_B",timeframe,volume) +
         request.security("OMXSTO:HEXA_B",timeframe,volume) +
         request.security("OMXSTO:HM_B",timeframe,volume) + 
         request.security("OMXSTO:INVE_B",timeframe,volume) + 
         request.security("OMXSTO:KINV_B",timeframe,volume) +  
         request.security("OMXSTO:NDA_SE",timeframe,volume) + 
         request.security("OMXSTO:NIBE_B",timeframe,volume) + 
         request.security("OMXSTO:SAND",timeframe,volume) + 
         request.security("OMXSTO:SBB_B",timeframe,volume) + 
         request.security("OMXSTO:SCA_B",timeframe,volume) + 
         request.security("OMXSTO:SEB_A",timeframe,volume) + 
         request.security("OMXSTO:SHB_A",timeframe,volume) +
         request.security("OMXSTO:SINCH",timeframe,volume) + 
         request.security("OMXSTO:SKF_B",timeframe,volume) + 
         request.security("OMXSTO:SWED_A",timeframe,volume) +  
         request.security("OMXSTO:TEL2_B",timeframe,volume) + 
         request.security("OMXSTO:TELIA",timeframe,volume) + 
         request.security("OMXSTO:VOLV_B",timeframe,volume)



//Since the first and last bar per day is so much larger than the rest it can be filtered out to make the scale more readable
t=1

if timefilter and timeframe=="1"
    t := time(timeframe.period, "0901-1729")
    
if timefilter and timeframe=="5"
    t := time(timeframe.period, "0906-1724")

if timefilter and timeframe=="15"
    t := time(timeframe.period, "0915-1714")

if timefilter and timeframe=="30"
    t := time(timeframe.period, "0930-1659")


// WILDERS MA
float volumeMA  = 0

if t // If timefilter is used the MA does not take into account the first and last bar and the VSA is more useful
    volumeMA := nz(volumeMA[1]) + (totvol-nz(volumeMA[1])) / lengthVolumeMA

ultraHighVolumeMin   = volumeMA * ratioUltraVolume
veryHighVolumeMin    = volumeMA * ratioVeryHighVolume
highVolumeMin        = volumeMA * ratioHighVolume
normalVolumeMin      = volumeMA * ratioNormalVolume
lowVolumeMin         = volumeMA * ratioLowVolume
veryLowVolumeMin     = volumeMA * ratioVeryLowVolume

volUltraHigh        = totvol >= ultraHighVolumeMin                                      ? true : false
volVeryHigh         = totvol >= veryHighVolumeMin   and totvol < ultraHighVolumeMin     ? true : false
volHigh             = totvol >= highVolumeMin       and totvol < veryHighVolumeMin      ? true : false
volNormal           = totvol >= normalVolumeMin     and totvol < highVolumeMin          ? true : false
volLow              = totvol >= lowVolumeMin        and totvol < normalVolumeMin        ? true : false
volVeryLow          = totvol < lowVolumeMin                                             ? true : false

// Determine histogram bar colour
palette = close>open ? color.green : color.red

if showVolumeChange
    palette := totvol>totvol[1] ? color.aqua : color.orange

if showVSA
    palette := volUltraHigh ? color.purple : volVeryHigh ? color.red : volHigh ? color.orange : volNormal ? color.green : volLow ? color.blue : color.silver

plot(na(t) ? na : totvol, color = palette, style=plot.style_columns, title="Volume", transp=0)
plot(showMA ? volumeMA : na, style=plot.style_line, color=color.green, title="Volume MA")

