nVPSA - Normalized Volume-Price Spread Analysis
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © TradingCat79

//@version=5
indicator("nVPSA")
import TradingView/ta/5
//input
intradaybars = input(1440, "Bars number for intraday analysis","Below one day, all interval have same number")
hourbarsno = input(60, "Bars number for higher interval analysis","Above one day, all interval have same number")
vreglenght = input(14, "Linear regression length","Linear regression calculated from normalized volume")
sreglenght = input(14, "Linear regression length", "Linear regression calculated from normalized spread")
//variables
int barrange0 = na
spread = high - low 
voldown = volume[2] > volume[1] and volume[1] > volume[0]
sprdown = spread[2] > spread[1] and spread[1] > spread[0]


//timeframe test
if timeframe.isintraday
    barrange0 := intradaybars
else 
    barrange0 := 60

//calcs
volnorm = (volume/ta.highest(volume, barrange0))
sprnorm = (spread/ta.highest(spread, barrange0))
volstd = ta.stdev(volume, barrange0)
normvolstd = ta.stdev(volnorm, barrange0)
sprstd = ta.stdev(spread, barrange0)
normsprstd = ta.stdev(sprnorm, barrange0)
gbv = volnorm == 1 
gbs = sprnorm == 1
regv = ta.linreg(volnorm, vreglenght, 0)
regs = ta.linreg(sprnorm, sreglenght, 0)
//plots
plot(volnorm, title='Normalized volume', color = (gbv) ? color.yellow: (volnorm > 4*normvolstd) ? color.fuchsia: (volnorm < 4*normvolstd) and (volnorm > 2*normvolstd) ? color.red : (volnorm < 2*normvolstd) and (volnorm > normvolstd) ? color.green : (volnorm < normvolstd) ? color.blue : color.rgb(59, 255, 222, 50), style = plot.style_columns)
plotcandle(0,0,0, sprnorm, "Normalized price spread", color = (gbs) ? color.yellow: (sprnorm > 4*normsprstd) ? color.rgb(223, 64, 251, 50): (sprnorm < 4*normsprstd) and (sprnorm > 2*normsprstd) ? color.rgb(255, 82, 82, 50) : (sprnorm < 2*normsprstd) and (sprnorm > normsprstd) ? color.rgb(76, 175, 79, 50) : (sprnorm < normsprstd) ? color.rgb(33, 149, 243, 50) : color.rgb(59, 255, 222, 50))

plot(regv, color= voldown ? color.black: (volume[1]<volume[0]) ? color.green: color.red, linewidth = 2, style = plot.style_cross)
plot(regs, color= sprdown ? color.black: (spread[1]<spread[0]) ? color.green: color.red, linewidth = 2, style = plot.style_circles)
//alerts
alertcondition(gbv or gbs, "VPSA Golden Bar", "Golden Bar now on chart!")
alertcondition(volnorm > 4*normvolstd, "Volume > 4Vstd", "Volume > 4Vstd")
alertcondition((volnorm < 4*normvolstd) and (volnorm > 2*normvolstd), "Volume > 2Vstd", "Volume > 2Vstd")
alertcondition((volnorm < 2*normvolstd) and (volnorm > normvolstd), "Volume > Vstd", "Volume > Vstd!") 
alertcondition((volnorm < normvolstd), "Volume < Vstd", "Volume < Vstd")
alertcondition((sprnorm > 4*normsprstd),"Spread > 4Sstd", "Spread > 4Sst")
alertcondition((sprnorm < 4*normsprstd) and (sprnorm > 2*normsprstd), "Spread > 2Sstd", "Spread > 2Sstd")
alertcondition((sprnorm < 2*normsprstd) and (sprnorm > normsprstd), "Spread > Sstd", "Spread > Sstd")
alertcondition((sprnorm < normsprstd), "Spread < Sstd", "Spread < Sstd")