Volume Weighted Real Relative Strength (RS/RW)
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © dealsatm
// @version=5

indicator(title="Volume Weighted Real Relative Strength", shorttitle="VRRS")


// Input section
RefTicker           = input.symbol(title="Market Reference", defval="SPY")
Sector_Auto_Selection = input.bool(title="Auto Sector Selection", defval=true)
SecTicker           = input.symbol(title="Sector Reference", defval="SPY")
Volume_Weighted     = input.bool(title="Volume Weighted", defval=true)
gap                 = input( title="Plot Gap", defval=0)
RollingLength       = input( title="Rolling Length", defval=21)
RollingLength_short = input( title="Rolling Length for Vol (Short term)", defval=21)
RollingLength_long  = input( title="Rolling Length for Vol (Long  term, Days)", defval=5)
upper = input(title="Upper", defval=1)
lower = input(title="Lower", defval=-1)

// Input for rate of change VRRS
length        = input( title = "Length for linear regression", defval = 6 )
bullish_rate  = input.float( title = "Bullish change rate (%/bar)", defval = 0.25 )
bullish_color = input.color( title = "Bullish color", defval = color.green )
bearish_rate  = input.float( title = "Bearish change rate (%/bar)", defval = -0.25 )
bearish_color = input.color( title = "Bearish color", defval = color.red )


// Sector database, load all at once
XLC = array.from("ATVI","CHTR","CMCSA","DIS","DISCA","DISCK","DISH","EA","FB","FOX","FOXA","GOOG","GOOGL","IPG","LUMN","LYV","MTCH","NFLX","NWS","NWSA","OMC","T","TMUS","TTWO","TWTR","VIAC","VZ")
XLY = array.from("AAP","AMZN","APTV","AZO","BBWI","BBY","BKNG","BWA","CCL","CMG","CZR","DG","DHI","DLTR","DPZ","DRI","EBAY","ETSY","EXPE","F","GM","GPC","GPS","GRMN","HAS","HD","HLT","KMX","LEN","LKQ","LOW","LVS","MAR","MCD","MGM","MHK","NCLH","NKE","NVR","NWL","ORLY","PENN","PHM","POOL","PVH","RCL","RL","ROST","SBUX","TGT","TJX","TPR","TSCO","TSLA","UA","UAA","ULTA","VFC","WHR","WYNN","YUM")
XLP = array.from("ADM","BF.B","CAG","CHD","CL","CLX","COST","CPB","EL","GIS","HRL","HSY","K","KHC","KMB","KO","KR","LW","MDLZ","MKC","MNST","MO","PEP","PG","PM","SJM","STZ","SYY","TAP","TSN","WBA","WMT")
XLE = array.from("APA","BKR","COP","CTRA","CVX","DVN","EOG","FANG","HAL","HES","KMI","MPC","MRO","OKE","OXY","PSX","PXD","SLB","VLO","WMB","XOM")
XLF = array.from("AFL","AIG","AIZ","AJG","ALL","AMP","AON","AXP","BAC","BEN","BK","BLK","BRK.B","BRO","C","CB","CBOE","CFG","CINF","CMA","CME","COF","DFS","FDS","FITB","FRC","GL","GS","HBAN","HIG","ICE","IVZ","JPM","KEY","L","LNC","MCO","MET","MKTX","MMC","MS","MSCI","MTB","NDAQ","NTRS","PBCT","PFG","PGR","PNC","PRU","RE","RF","RJF","SBNY","SCHW","SIVB","SPGI","STT","SYF","TFC","TROW","TRV","USB","WFC","WRB","WTW","ZION")
XLV = array.from("A","ABBV","ABC","ABMD","ABT","ALGN","AMGN","ANTM","BAX","BDX","BIIB","BIO","BMY","BSX","CAH","CERN","CI","CNC","COO","CRL","CTLT","CVS","DGX","DHR","DVA","DXCM","EW","GILD","HCA","HOLX","HSIC","HUM","IDXX","ILMN","INCY","IQV","ISRG","JNJ","LH","LLY","MCK","MDT","MRK","MRNA","MTD","OGN","PFE","PKI","REGN","RMD","STE","SYK","TECH","TFX","TMO","UHS","UNH","VRTX","VTRS","WAT","WST","XRAY","ZBH","ZTS")
XLI = array.from("AAL","ALK","ALLE","AME","AOS","BA","CARR","CAT","CHRW","CMI","CPRT","CSX","CTAS","DAL","DE","DOV","EFX","EMR","ETN","EXPD","FAST","FBHS","FDX","FTV","GD","GE","GNRC","GWW","HII","HON","HWM","IEX","INFO","IR","ITW","J","JBHT","JCI","LDOS","LHX","LMT","LUV","MAS","MMM","NLSN","NOC","NSC","ODFL","OTIS","PCAR","PH","PNR","PWR","RHI","ROK","ROL","ROP","RSG","RTX","SNA","SWK","TDG","TT","TXT","UAL","UNP","UPS","URI","VRSK","WAB","WM","XYL")
XLB = array.from("ALB","AMCR","APD","AVY","BLL","CE","CF","CTVA","DD","DOW","ECL","EMN","FCX","FMC","IFF","IP","LIN","LYB","MLM","MOS","NEM","NUE","PKG","PPG","SEE","SHW","VMC","WRK")
XLRE = array.from("AMT","ARE","AVB","BXP","CBRE","CCI","DLR","DRE","EQIX","EQR","ESS","EXR","FRT","HST","IRM","KIM","MAA","O","PEAK","PLD","PSA","REG","SBAC","SPG","UDR","VNO","VTR","WELL","WY")
XLK = array.from("AAPL","ACN","ADBE","ADI","ADP","ADSK","AKAM","AMAT","AMD","ANET","ANSS","APH","AVGO","BR","CDAY","CDNS","CDW","CRM","CSCO","CTSH","CTXS","DXC","ENPH","EPAM","FFIV","FIS","FISV","FLT","FTNT","GLW","GPN","HPE","HPQ","IBM","INTC","INTU","IPGP","IT","JKHY","JNPR","KEYS","KLAC","LRCX","MA","MCHP","MPWR","MSFT","MSI","MU","NLOK","NOW","NTAP","NVDA","NXPI","ORCL","PAYC","PAYX","PTC","PYPL","QCOM","QRVO","SEDG","SNPS","STX","SWKS","TDY","TEL","TER","TRMB","TXN","TYL","V","VRSN","WDC","XLNX","ZBRA")
XLU = array.from("AEE","AEP","AES","ATO","AWK","CMS","CNP","D","DTE","DUK","ED","EIX","ES","ETR","EVRG","EXC","FE","LNT","NEE","NI","NRG","PEG","PNW","PPL","SO","SRE","WEC","XEL")


get_sector_close( _Ticker ) =>
    request.security(symbol=_Ticker, timeframe="", expression=close)
    
cal_VRRS(_TickerClose, _RefClose,_VolWeight, _RollingLength) =>
    _TickerSMA    = ta.sma( _TickerClose, _RollingLength)
    _TickerChange = _TickerClose - _TickerSMA[1]
    _RefSMA       = ta.sma( _RefClose, _RollingLength)
    _RefChange    = _RefClose - _RefSMA[1]
    (_TickerChange/_TickerSMA[1] - _RefChange/_RefSMA[1])  * _VolWeight * 100
    

factor = 78
if str.contains(timeframe.period,'D')
    factor := 1
if str.contains(timeframe.period,'S')
    factor := 1
if str.contains(timeframe.period,'W')
    factor := 1
if str.contains(timeframe.period,'M')
    factor := 1

RollingLength_long := RollingLength_long * factor

//##########Rolling Price Change##########
RefClose      = request.security(symbol=RefTicker, timeframe="", expression=close)
RefOpen       = request.security(symbol=RefTicker, timeframe="", expression=open)
RefHigh       = request.security(symbol=RefTicker, timeframe="", expression=high)
RefLow        = request.security(symbol=RefTicker, timeframe="", expression=low)
RefSMA        = request.security(symbol=RefTicker, timeframe="", expression=ta.sma(close,RollingLength) )
RefSMAD       = request.security(symbol=RefTicker, timeframe="D", expression=ta.sma(close,1) )
RefCloseD     = request.security(symbol=RefTicker, timeframe="D", expression=close)
Refdo = request.security(symbol=RefTicker, timeframe="D", expression=open  )


//Volume sma
AvgVol_long = ta.sma(volume,RollingLength_long)
AvgVol_short = ta.sma(volume,RollingLength_short)

//##########Calculations##########
VolWeight = AvgVol_short[1]/AvgVol_long[1]
if not Volume_Weighted
    VolWeight := 1

// VRSS vs Market (1st reference)
VRRS = cal_VRRS(close, RefClose, VolWeight, RollingLength)

// VRSS vs SecTicker (2st Reference). Calculate it even if we do not need
SecClose = get_sector_close( SecTicker )
SecVRRS  = cal_VRRS(close, SecClose, VolWeight, RollingLength)

XSecVRRS = switch
    array.includes(XLC, syminfo.ticker) => cal_VRRS(close, get_sector_close( 'XLC' ), VolWeight, RollingLength)
    array.includes(XLY, syminfo.ticker) => cal_VRRS(close, get_sector_close( 'XLY' ), VolWeight, RollingLength)
    array.includes(XLP, syminfo.ticker) => cal_VRRS(close, get_sector_close( 'XLP' ), VolWeight, RollingLength)
    array.includes(XLE, syminfo.ticker) => cal_VRRS(close, get_sector_close( 'XLE' ), VolWeight, RollingLength)
    array.includes(XLF, syminfo.ticker) => cal_VRRS(close, get_sector_close( 'XLF' ), VolWeight, RollingLength)
    array.includes(XLV, syminfo.ticker) => cal_VRRS(close, get_sector_close( 'XLV' ), VolWeight, RollingLength)
    array.includes(XLI, syminfo.ticker) => cal_VRRS(close, get_sector_close( 'XLI' ), VolWeight, RollingLength)
    array.includes(XLB, syminfo.ticker) => cal_VRRS(close, get_sector_close( 'XLB' ), VolWeight, RollingLength)
    array.includes(XLRE, syminfo.ticker) => cal_VRRS(close, get_sector_close( 'XLRE' ), VolWeight, RollingLength)
    array.includes(XLK, syminfo.ticker) => cal_VRRS(close, get_sector_close( 'XLK' ), VolWeight, RollingLength)
    array.includes(XLU, syminfo.ticker) => cal_VRRS(close, get_sector_close( 'XLU' ), VolWeight, RollingLength)
    =>SecVRRS

UseSecTicker = switch
    array.includes(XLC, syminfo.ticker) => 'XLC'
    array.includes(XLY, syminfo.ticker) => 'XLY'
    array.includes(XLP, syminfo.ticker) => 'XLP'
    array.includes(XLE, syminfo.ticker) => 'XLE'
    array.includes(XLF, syminfo.ticker) => 'XLF'
    array.includes(XLV, syminfo.ticker) => 'XLV'
    array.includes(XLI, syminfo.ticker) => 'XLI'
    array.includes(XLB, syminfo.ticker) => 'XLB'
    array.includes(XLRE, syminfo.ticker) => 'XLRE'
    array.includes(XLK, syminfo.ticker) => 'XLK'
    array.includes(XLU, syminfo.ticker) => 'XLU'
    => array.get( str.split(SecTicker,':' ),1 )
    
if not Sector_Auto_Selection
    UseSecTicker := array.get( str.split(SecTicker,':' ),1 )
    
    
//##########Plot##########
// Plot VRRS vs ticker #1
RealRelativeStrength = plot(VRRS, title="VRRS vs Market", style=plot.style_columns, color=(VRRS>=0 ? (VRRS[1] < VRRS ? color.rgb(0,255,0,0) : color.rgb(150,255,150,0) ) : (VRRS[1] < VRRS ? color.rgb(255,150,150,0) : color.rgb(255,0,0,0))))
// Plot VRRS vs ticker #2
// This plot is taking time. Finding solution for it?
// If you want to disable this feature to speed up, put // at the begining of the following line
SecRealRelativeStrength = plot( not Sector_Auto_Selection ? SecVRRS + gap : XSecVRRS + gap, title="VRRS vs Sector", color=color.white)
// and remove the // at the begining of the following 2 lines
//SecRealRelativeStrength = plot( SecVRRS + gap, title="VRRS vs Sector", color=color.white)
//UseSecTicker := array.get( str.split(SecTicker,':' ),1 )

Baseline = plot(gap, "Baseline", color=color.black)
//fill(SecRealRelativeStrength, Baseline, color = SecVRRS >= 0 ? color.rgb(255,0,255,100) : color.rgb(250, 250, 0, 100), title="Fill color: Reference Ticker #2")
// Plot Change of ticker #1 vs close price of previous day
plotbar((RefOpen/RefCloseD-1)*100, (RefHigh/RefCloseD-1)*100, (RefLow/RefCloseD-1)*100, (RefClose/RefCloseD-1)*100, title="Reference Change", color = open < close ? color.rgb(255, 0, 255, 0) : color.rgb(255, 255, 0, 0))//, wickcolor=open < close ? color.white : color.lime)


// Draw horizontal line
upperline = plot(upper, "Upper limmit", color=color.gray)
lowerline = plot(lower, "Lower limmit", color=color.gray)

// Calculate rate of change
X = bar_index
Y = VRRS
Y_ = ta.linreg( Y, length, 0 )
rate = Y_[0]-Y_[1]
correlation = ta.correlation( Y, Y_, length )
// Show data
var tbl = table.new( position.bottom_left, 6, 1, frame_color = color.yellow,  frame_width=1, border_width=2, border_color=color.new(color.white, 100) )
rate_color = rate[0] >= bullish_rate ? bullish_color : ( rate[0] <= bearish_rate ? bearish_color : color.black )
table.cell( tbl, 0, 0, 'Change Rate',  text_halign = text.align_center, bgcolor = color.gray, text_color = color.white, text_size = size.small)
table.cell( tbl, 1, 0, str.tostring(rate[0],"#.##")+' %/bar',  text_halign = text.align_center, bgcolor = rate_color, text_color = color.white, text_size = size.small)
table.cell( tbl, 2, 0, 'Certainty',  text_halign = text.align_center, bgcolor = color.gray, text_color = color.white, text_size = size.small)
table.cell( tbl, 3, 0, str.tostring(correlation[0]*100,"#.##")+'%',  text_halign = text.align_center, bgcolor = rate_color, text_color = color.white, text_size = size.small)
table.cell( tbl, 4, 0, 'Sector Ref',  text_halign = text.align_center, bgcolor = color.gray, text_color = color.white, text_size = size.small)
table.cell( tbl, 5, 0, UseSecTicker,  text_halign = text.align_center, bgcolor = color.black, text_color = color.white, text_size = size.small)
