RS - Relative Strength Score
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// ©Lantzwat

//@version=5
indicator("RS - Relative Strength Score", "RS")

src             = input(title='Source', defval=close)
RefTickerId     = input.symbol("SP:SPX+NASDAQ_DLY:NDX+DJ:DWCPF", title="Reference index", tooltip = "e.g. SPX/NDX/RUT/DWCPF or combinations of it, or TOTAL for Crypto")
bRSI            = input.bool(true, "Show Relative Strength - annual based (IBD Style)")
bRSIQuarterly   = input.bool(true, "Show Relative Strength - quarterly based")

// default lines
p0 = plot(0, color = color.new(color.white,100))
hline(0,  "0" , linestyle = hline.style_dotted, color = color.new(color.white,90) )
hline(30, "30", linestyle = hline.style_dotted, color = color.new(color.white,70) )
hline(60, "60", linestyle = hline.style_dotted, color = color.new(color.white,70) )

var table infoTable = table.new(position.top_right, 1, 1, border_width = 0)
f_fillCell(_table, _column, _row, _value) =>
	_cellText = str.tostring(_value, "#.##")
	table.cell(_table, _column, _row, _cellText, text_size = size.tiny, text_color = color.white)
f_fillCelltext(_table, _column, _row, _value) =>
	_cellText = _value
	table.cell(_table, _column, _row, _cellText, text_size = size.tiny, text_color = color.white)

// Calculate relative strength
RS(tf, baseSymbol,comparativeSymbol, q) =>
    // RS Score (Additional Momentum Parameter IBD Style)

    // checking if traded 5 days a week (stock) or 7 days a week (crypto, forex)
    lb_day = dayofweek(time('D')) == dayofweek(time('D')[7]) ? 365 : 251
    lb_week = 52

    // calculate default values
    m3 = 0
    m6 = 0
    m9 = 0
    m12 = 0
    if tf == "W"
        m3  := int(lb_week / 4)        
        m6  := int(lb_week / 2)
        m9  := int((lb_week  * 3) / 4)
        m12 := lb_week
    else if tf == "D" // default
        m3  := int(lb_day / 4) 
        m6  := int(lb_day / 2) 
        m9  := int((lb_day * 3 )/ 4) 
        m12 := lb_day        

    rs_score = 0.
    if m3 != 0 
        rs_score_3m = (baseSymbol / baseSymbol[m3] / (comparativeSymbol / comparativeSymbol[m3]) - 1)
        rs_score_6m = (baseSymbol / baseSymbol[m6] / (comparativeSymbol / comparativeSymbol[m6]) - 1)
        rs_score_9m = (baseSymbol / baseSymbol[m9] / (comparativeSymbol / comparativeSymbol[m9]) - 1)
        rs_score_12m = (baseSymbol / baseSymbol[m12] / (comparativeSymbol / comparativeSymbol[m12]) - 1)

        if q == 4 
            rs_score := (0.4 * rs_score_3m + 0.2 * rs_score_6m + 0.2 * rs_score_9m + 0.2 * rs_score_12m) * 100
        if q == 1
            rs_score := (rs_score_3m) * 100
    else
        f_fillCelltext(infoTable, 0, 0, "Only valid in daily and weekly timeframe")

    rs_score

reference_close = request.security(RefTickerId, timeframe.period, src)

// plot RS quarterly
relative_strength_quarter   = RS(timeframe.period, src,reference_close,1)
RSQcolor                    = relative_strength_quarter <= 0 ? color.red : relative_strength_quarter < 10 ? color.from_gradient(relative_strength_quarter, 0, 10, color.yellow, color.yellow ) : relative_strength_quarter < 60 ? color.from_gradient(relative_strength_quarter, 10, 60, color.green , color.blue) : color.from_gradient(relative_strength_quarter, 60, 100, color.blue , color.navy)
pRSq                        = plot(bRSIQuarterly ? relative_strength_quarter : na, color = RSQcolor, linewidth = 1)
fill(p0,pRSq,color = color.new(RSQcolor,70))

// plot RS annual (IBD style)
relative_strength           = RS(timeframe.period, src,reference_close,4)
RScolor                     = relative_strength <= 0 ? color.red : relative_strength < 10 ? color.from_gradient(relative_strength, 0, 10, color.yellow, color.yellow ) : relative_strength < 60 ? color.from_gradient(relative_strength, 10, 60, color.green , color.blue) : color.from_gradient(relative_strength, 60, 100, color.blue , color.navy)
pRS                         = plot(bRSI ? relative_strength : na, color = RScolor, linewidth = 3)
fill(p0,pRS,color = color.new(RScolor,70))
f_fillCell(infoTable, 0, 0, relative_strength)

