Relative Performance
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © millerrh

// This script takes the Performance Indicator that was first published when tables were introduced (from @BeeHolder) and compares the performance of the chart
// ticker to the performance of a selected index/ticker. It also shows the monthly volatility (per stock screener) which is similar to ADR.

//@version=5
indicator('Relative Performance', overlay=false)

var table perfTable = table.new(position.middle_left, 9, 2, border_width=3)

lightTransp = 90
avgTransp = 80
heavyTransp = 70

// === USER INPUTS ===
i_posColor = input(color.rgb(38, 166, 154), title='Positive Color')
i_negColor = input(color.rgb(240, 83, 80), title='Negative Color')
i_volColor = input(color.new(#999999, 0), title='Volatility Color')
sym = input.symbol(title='Index/Ticker Compare', defval='SPY')

f_rateOfreturn(_v1, _v2) =>
    (_v1 - _v2) * 100 / math.abs(_v2)

f_performance(sec, _barsBack) =>
    request.security(sec, '1D', f_rateOfreturn(close, close[_barsBack]))

recentClose(sec) =>
    request.security(sec, '1D', close)

lastYearClose(sec) =>
    request.security(sec, '12M', close[1], lookahead=barmerge.lookahead_on)

f_fillCell(_table, _column, _row, _value, _timeframe) =>
    _c_color = _value >= 0 ? i_posColor : i_negColor
    _transp = math.abs(_value) > 10 ? heavyTransp : math.abs(_value) > 5 ? avgTransp : lightTransp
    _cellText = str.tostring(_value, '0.00') + '%\n' + _timeframe
    table.cell(_table, _column, _row, _cellText, bgcolor=color.new(_c_color, _transp), text_color=_c_color, width=6)

volatility(sec) =>  // Monthly Volatility in Stock Screener (also ADR)
    request.security(sec, 'D', ta.sma((high - low) / math.abs(low) * 100, 21))

fiftyTwoHighDiff(sec) =>
    fiftyTwoHigh = request.security(sec, 'W', ta.highest(high, 52))
    request.security(sec, '1D', ((fiftyTwoHigh - close)/fiftyTwoHigh)*100)

f_fillCellVol(_table, _column, _row, _value) =>
    _transp = math.abs(_value) > 7 ? heavyTransp : math.abs(_value) > 4 ? avgTransp : lightTransp
    _cellText = str.tostring(_value, '0.00') + '%\n' + 'ADR'
    table.cell(_table, _column, _row, _cellText, bgcolor=color.new(i_volColor, _transp), text_color=i_volColor, width=6)
    
f_fillCellFiftyTwo(_table, _column, _row, _value) =>
    _c_color = _value <= 25 ? i_posColor : i_negColor
    _transp = math.abs(_value) <= 10 ? heavyTransp : math.abs(_value) <= 15 ? avgTransp : lightTransp
    _cellText = str.tostring(_value, '0.0') + '%\n' + 'OFF 52WK HIGH'
    table.cell(_table, _column, _row, _cellText, bgcolor=color.new(_c_color, _transp), text_color=_c_color, width=10)

f_fillCellSec(_table, _column, _row, _value) =>
    table.cell(_table, _column, _row, _value, bgcolor=color.new(i_volColor, avgTransp), text_color=i_volColor, width=12)

if barstate.islast
    f_fillCellSec(perfTable, 0, 0, syminfo.ticker)
    f_fillCell(perfTable, 1, 0, f_performance(syminfo.tickerid, 5), '1W')
    f_fillCell(perfTable, 2, 0, f_performance(syminfo.tickerid, 21), '1M')
    f_fillCell(perfTable, 3, 0, f_performance(syminfo.tickerid, 63), '3M')
    f_fillCell(perfTable, 4, 0, f_performance(syminfo.tickerid, 126), '6M')
    f_fillCell(perfTable, 5, 0, f_rateOfreturn(recentClose(syminfo.tickerid), lastYearClose(syminfo.tickerid)), 'YTD')
    f_fillCell(perfTable, 6, 0, f_performance(syminfo.tickerid, 251), '1Y')
    f_fillCellVol(perfTable, 7, 0, volatility(syminfo.tickerid))
    f_fillCellFiftyTwo(perfTable, 8, 0, fiftyTwoHighDiff(syminfo.tickerid))
    f_fillCellSec(perfTable, 0, 1, sym)
    f_fillCell(perfTable, 1, 1, f_performance(sym, 5), '1W')
    f_fillCell(perfTable, 2, 1, f_performance(sym, 21), '1M')
    f_fillCell(perfTable, 3, 1, f_performance(sym, 63), '3M')
    f_fillCell(perfTable, 4, 1, f_performance(sym, 126), '6M')
    f_fillCell(perfTable, 5, 1, f_rateOfreturn(recentClose(sym), lastYearClose(sym)), 'YTD')
    f_fillCell(perfTable, 6, 1, f_performance(sym, 251), '1Y')
    f_fillCellVol(perfTable, 7, 1, volatility(sym))
    f_fillCellFiftyTwo(perfTable, 8, 1, fiftyTwoHighDiff(sym))

