Cobra's CryptoMarket Visualizer
// This work is licensed under a Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) https://creativecommons.org/licenses/by-nc-sa/4.0/
// © EliCobra

//@version=5
indicator("Cobra's Crypto Market Visualizer", "{Ʌ} - 𝐂𝐫𝐲𝐩𝐭𝐨 𝐕𝐢𝐬𝐮𝐚𝐥𝐢𝐳𝐞𝐫", true, scale = scale.none)

type asset 
    string name
    float beta
    float alpha
    float sharpe
    float sortino
    float omega
    float zscore
    float athdd
    float adr

method copyasset(asset this) =>
    asset.new(this.name, this.beta, this.alpha, this.sharpe, this.sortino, this.omega, this.zscore, this.athdd, this.adr)

f_beta(src, base, lookback) =>
    float daily_return = src / src[1] - 1
    float daily_base_return = base / base[1] - 1
    returns_array = array.new_float(0)
    returns_base_array = array.new_float(0)

    for i = 0 to lookback
        array.push(returns_array, daily_return[i])
        array.push(returns_base_array, daily_base_return[i])

    array.covariance(returns_array, returns_base_array) / array.variance(returns_base_array)

f_alpha(src, base, period, lookback) =>
    float daily_return = src / src[1] - 1
    float daily_base_return = base / base[1] - 1
    returns_array = array.new_float(0)
    returns_base_array = array.new_float(0)
    
    for i = 0 to period
        array.push(returns_array, daily_return[i])
        array.push(returns_base_array, daily_base_return[i])

    array.sum(returns_array) - array.sum(returns_base_array) * f_beta(src, base, lookback)

f_sharpe(src, lookback) =>
    float daily_return = src / src[1] - 1
    returns_array = array.new_float(0)
    for i = 0 to lookback
        array.push(returns_array, daily_return[i])
    
    standard_deviation = array.stdev(returns_array)
    mean = array.avg(returns_array)
    
    math.round(mean / standard_deviation * math.sqrt(lookback), 2)

f_sortino(src, lookback) =>
    float daily_return = src / src[1] - 1
    returns_array = array.new_float(0)
    negative_returns_array = array.new_float(0)
    for i = 0 to lookback
        array.push(returns_array, daily_return[i])
        if daily_return[i] <= 0.0
            array.push(negative_returns_array, daily_return[i])


    negative_returns_standard_deviation = array.stdev(negative_returns_array)
    mean = array.avg(returns_array)
    
    math.round(mean / negative_returns_standard_deviation * math.sqrt(lookback), 2)

f_omega(src, lookback) =>
    float daily_return = src / src[1] - 1
    negative_returns_array = array.new_float(0)
    positive_returns_array = array.new_float(0)
    for i = 0 to lookback
        if daily_return[i] <= 0.0
            array.push(negative_returns_array, daily_return[i])
        else
            array.push(positive_returns_array, daily_return[i])

    postive_area = array.sum(positive_returns_array)
    negative_area = array.sum(negative_returns_array) * (-1)
    
    math.round(postive_area / negative_area, 2)

f_zscore(src, lookback) =>
    (src - ta.sma(src, lookback)) / ta.stdev(src, lookback)

f_ath_dd(_src) => 
    var ath = 0.0
    if _src > ath
        ath := _src
    
    _src / ath - 1

f_ADR(lookback) =>
    ta.sma(high / low, lookback) - 1

f_calc(coin, src, base, alphaper, adrlen, lookback) =>
    asset ass = request.security("BINANCE:" + coin + "USDT.P", timeframe.period,
         asset.new(coin, f_beta(src, base, lookback), f_alpha(src, base, alphaper, lookback), f_sharpe(src, lookback), 
         f_sortino(src, lookback), f_omega(src, lookback), f_zscore(src, lookback), f_ath_dd(src), f_ADR(adrlen)))

    ass

f_col(i, y) =>
    var color col_dn = #4B0082
    var color col_up = #db4d19
    x = switch i
        2 => y < 1 ? color.from_gradient(y, 0, 1, col_dn, color.new(col_dn, 90)) : color.from_gradient(y, 1, 2, color.new(col_up, 90), col_up)
        3 => y < 0 ? color.from_gradient(y, -2, 0, col_dn, color.new(col_dn, 90)) : color.from_gradient(y, 0, 2, color.new(col_up, 90), col_up)
        4 => y < 1 ? color.from_gradient(y, 0, 1, col_dn, color.new(col_dn, 90)) : color.from_gradient(y, 1, 2, color.new(col_up, 90), col_up)
        5 => y < 1.5 ? color.from_gradient(y, 0, 1.5, col_dn, color.new(col_dn, 90)) : color.from_gradient(y, 1.5, 2.5, color.new(col_up, 90), col_up)
        6 => y < 1 ? color.from_gradient(y, 0.8, 1, col_dn, color.new(col_dn, 90)) : color.from_gradient(y, 1, 1.25, color.new(col_up, 90), col_up)
        7 => y < 0 ? color.from_gradient(y, -1.5, 0, col_dn, color.new(col_dn, 90)) : color.from_gradient(y, 0, 1.5, color.new(col_up, 90), col_up)
        8 => #000000
        9 => #000000

    x

f_pos(string position) =>
    pos = switch position
        "Top Left" => position.top_left
        "Middle Left" => position.middle_left
        "Bottom Left" => position.bottom_left
        "Top Right" => position.top_right
        "Middle Right" => position.middle_right
        "Bottom Right" => position.bottom_right
        "Top Center" => position.top_center
        "Bottom Center" => position.bottom_center
        "Center" => position.middle_center

    pos

set = input.int(1, "Asset Group", options = [1, 2, 3])
lookback = input.int(365, "Length")
alphaperiod = input.int(30, "Alpha Period")
adrper = input.int(14, "ADR Length")
src = input.source(hlc3, "Source Calculation")
pos_table = input.string("Bottom Right", "Table Position", options = ["Top Left", "Middle Left", "Bottom Left", "Top Right", "Middle Right", "Bottom Right", "Top Center", "Center", "Bottom Center"])
comp = input.bool(false, "Compress Table Size")
split = input.string("No", "Split Mode", options = ["No", "Top Half", "Bottom Half"])
base = request.security("BINANCE:BTCUSDT.P", timeframe.period, src)


// Assets {
var string name1 = switch set
    1 => "1000SHIB"
    2 => "1INCH"
    3 => "AAVE"

var string name2 = switch set
    1 => "ACH"
    2 => "ADA"
    3 => "AGIX"

var string name3 = switch set
    1 => "ALGO"
    2 => "ALICE"
    3 => "ALPHA"

var string name4 = switch set
    1 => "ANKR"
    2 => "ANT"
    3 => "APE"

var string name5 = switch set
    1 => "API3"
    2 => "APT"
    3 => "ARPA"

var string name6 = switch set
    1 => "AR"
    2 => "ATOM"
    3 => "AVAX"

var string name7 = switch set
    1 => "AXS"
    2 => "BAND"
    3 => "BAT"

var string name8 = switch set
    1 => "BCH"
    2 => "BNB"
    3 => "BTC"

var string name9 = switch set
    1 => "CFX"
    2 => "CHR"
    3 => "CHZ"

var string name10 = switch set
    1 => "SUI"
    2 => "COMP"
    3 => "COTI"
var string name11 = switch set
    1 => "CRV"
    2 => "DOGE"
    3 => "DOT"

var string name12 = switch set
    1 => "DUSK"
    2 => "DYDX"
    3 => "EGLD"

var string name13 = switch set
    1 => "ENJ"
    2 => "ENS"
    3 => "ETC"

var string name14 = switch set
    1 => "ETH"
    2 => "FET"
    3 => "FIL"

var string name15 = switch set
    1 => "FLM"
    2 => "FLOW"
    3 => "FOOTBALL"

var string name16 = switch set
    1 => "FTM"
    2 => "FXS"
    3 => "GALA"

var string name17 = switch set
    1 => "GAL"
    2 => "GMT"
    3 => "GMX"

var string name18 = switch set
    1 => "GRT"
    2 => "HFT"
    3 => "HIGH"

var string name19 = switch set
    1 => "HOOK"
    2 => "ICP"
    3 => "IMX"

var string name20 = switch set
    1 => "INJ"
    2 => "JASMY"
    3 => "JOE"

var string name21 = switch set
    1 => "KAVA"
    2 => "KLAY"
    3 => "KNC"

var string name22 = switch set
    1 => "KSM"
    2 => "LDO"
    3 => "LINA"

var string name23 = switch set
    1 => "LINK"
    2 => "LIT"
    3 => "LQTY"

var string name24 = switch set
    1 => "LRC"
    2 => "LTC"
    3 => "MAGIC"

var string name25 = switch set
    1 => "MANA"
    2 => "MASK"
    3 => "MATIC"

var string name26 = switch set
    1 => "MINA"
    2 => "MTL"
    3 => "NEAR"

var string name27 = switch set
    1 => "NKN"
    2 => "OCEAN"
    3 => "OMG"

var string name28 = switch set
    1 => "ONE"
    2 => "ONT"
    3 => "OP"

var string name29 = switch set
    1 => "PEOPLE"
    2 => "PERP"
    3 => "PHB"

var string name30 = switch set
    1 => "QNT"
    2 => "QTUM"
    3 => "RDNT"

var string name31 = switch set
    1 => "REEF"
    2 => "RNDR"
    3 => "ROSE"

var string name32 = switch set
    1 => "RSR"
    2 => "RUNE"
    3 => "RVN"

var string name33 = switch set
    1 => "SAND"
    2 => "SKL"
    3 => "SNX"

var string name34 = switch set
    1 => "SOL"
    2 => "SSV"
    3 => "STG"

var string name35 = switch set
    1 => "STORJ"
    2 => "STX"
    3 => "SUSHI"

var string name36 = switch set
    1 => "SXP"
    2 => "THETA"
    3 => "TLM"

var string name37 = switch set
    1 => "BNT"
    2 => "TRB"
    3 => "TRU"

var string name38 = switch set
    1 => "TRX"
    2 => "UNFI"
    3 => "UNI"

var string name39 = switch set
    1 => "WAVES"
    2 => "XLM"
    3 => "XMR"

var string name40 = switch set
    1 => "XRP"
    2 => "XTZ"
    3 => "ZEC"
// Assets End }

asset1 = f_calc(name1, src, base, alphaperiod, adrper, lookback)
asset2 = f_calc(name2, src, base, alphaperiod, adrper, lookback)
asset3 = f_calc(name3, src, base, alphaperiod, adrper, lookback)
asset4 = f_calc(name4, src, base, alphaperiod, adrper, lookback)
asset5 = f_calc(name5, src, base, alphaperiod, adrper, lookback)
asset6 = f_calc(name6, src, base, alphaperiod, adrper, lookback)
asset7 = f_calc(name7, src, base, alphaperiod, adrper, lookback)
asset8 = f_calc(name8, src, base, alphaperiod, adrper, lookback)
asset9 = f_calc(name9, src, base, alphaperiod, adrper, lookback)
asset10 = f_calc(name10, src, base, alphaperiod, adrper, lookback)
asset11 = f_calc(name11, src, base, alphaperiod, adrper, lookback)
asset12 = f_calc(name12, src, base, alphaperiod, adrper, lookback)
asset13 = f_calc(name13, src, base, alphaperiod, adrper, lookback)
asset14 = f_calc(name14, src, base, alphaperiod, adrper, lookback)
asset15 = f_calc(name15, src, base, alphaperiod, adrper, lookback)
asset16 = f_calc(name16, src, base, alphaperiod, adrper, lookback)
asset17 = f_calc(name17, src, base, alphaperiod, adrper, lookback)
asset18 = f_calc(name18, src, base, alphaperiod, adrper, lookback)
asset19 = f_calc(name19, src, base, alphaperiod, adrper, lookback)
asset20 = f_calc(name20, src, base, alphaperiod, adrper, lookback)
asset21 = f_calc(name21, src, base, alphaperiod, adrper, lookback)
asset22 = f_calc(name22, src, base, alphaperiod, adrper, lookback)
asset23 = f_calc(name23, src, base, alphaperiod, adrper, lookback)
asset24 = f_calc(name24, src, base, alphaperiod, adrper, lookback)
asset25 = f_calc(name25, src, base, alphaperiod, adrper, lookback)
asset26 = f_calc(name26, src, base, alphaperiod, adrper, lookback)
asset27 = f_calc(name27, src, base, alphaperiod, adrper, lookback)
asset28 = f_calc(name28, src, base, alphaperiod, adrper, lookback)
asset29 = f_calc(name29, src, base, alphaperiod, adrper, lookback)
asset30 = f_calc(name30, src, base, alphaperiod, adrper, lookback)
asset31 = f_calc(name31, src, base, alphaperiod, adrper, lookback)
asset32 = f_calc(name32, src, base, alphaperiod, adrper, lookback)
asset33 = f_calc(name33, src, base, alphaperiod, adrper, lookback)
asset34 = f_calc(name34, src, base, alphaperiod, adrper, lookback)
asset35 = f_calc(name35, src, base, alphaperiod, adrper, lookback)
asset36 = f_calc(name36, src, base, alphaperiod, adrper, lookback)
asset37 = f_calc(name37, src, base, alphaperiod, adrper, lookback)
asset38 = f_calc(name38, src, base, alphaperiod, adrper, lookback)
asset39 = f_calc(name39, src, base, alphaperiod, adrper, lookback)

var metric = array.from("", "Asset", "Beta", "Alpha", "Sharpe", "Sortino", "Omega", "Z-Score", "ATH-DD", "ADR")
var tips = array.from("", "", "Beta: Measures how an asset's price moves compared to the overall market.", "Alpha: Measures an investment's excess return compared to its expected return, given its risk.",
 "Sharpe Ratio: Evaluates an investment's risk-adjusted return, considering the return per unit of risk taken.", "Sortino Ratio: Evaluates an investment's risk-adjusted return, focusing on downside risk.",
 "Omega Ratio: Measures the ratio of average positive returns to average negative returns, assessing reward-to-risk.", "Z-Score: Measures the distance of a data point from the mean in terms of standard deviations.",
 "ATH -DD: Current Drawdown from all time high", "Average Daily Range: Represents the average price range an asset moves within during a trading day.")

var table Main = table.new(f_pos(pos_table), 40, 10, border_color = #ffffff80, border_width = 1, frame_color = #ffffff80, frame_width = 1)
table.merge_cells(Main, split == "Bottom Half" ? 18 : 0, 0, split == "Top Half" ? 20 : 39, 0)

if barstate.islast
    table.cell(Main, split == "Bottom Half" ? 18 : 0, 0, "🐍 𝘾𝙤𝙗𝙧𝙖'𝙨 𝘾𝙧𝙮𝙥𝙩𝙤 𝙈𝙖𝙧𝙠𝙚𝙩 𝙑𝙞𝙨𝙪𝙖𝙡𝙞𝙯𝙚𝙧 🐍", text_color = #ffffff, bgcolor = #000000)

    for k = 1 to 9
        table.cell(Main, split == "Bottom Half" ? 18 : 0, k, array.get(metric, k), text_color = #ffffff, bgcolor = #000000, text_size = size.small, tooltip = array.get(tips, k))

    for i = split == "Bottom Half" ? 19 : 1 to split == "Top Half" ? 20 : 39
        asset assetbuff = switch i
            1 => asset1.copyasset()
            2 => asset2.copyasset()
            3 => asset3.copyasset()
            4 => asset4.copyasset()
            5 => asset5.copyasset()
            6 => asset6.copyasset()
            7 => asset7.copyasset()
            8 => asset8.copyasset()
            9 => asset9.copyasset()
            10 => asset10.copyasset()
            11 => asset11.copyasset()
            12 => asset12.copyasset()
            13 => asset13.copyasset()
            14 => asset14.copyasset()
            15 => asset15.copyasset()
            16 => asset16.copyasset()
            17 => asset17.copyasset()
            18 => asset18.copyasset()
            19 => asset19.copyasset()
            20 => asset20.copyasset()
            21 => asset21.copyasset()
            22 => asset22.copyasset()
            23 => asset23.copyasset()
            24 => asset24.copyasset()
            25 => asset25.copyasset()
            26 => asset26.copyasset()
            27 => asset27.copyasset()
            28 => asset28.copyasset()
            29 => asset29.copyasset()
            30 => asset30.copyasset()
            31 => asset31.copyasset()
            32 => asset32.copyasset()
            33 => asset33.copyasset()
            34 => asset34.copyasset()
            35 => asset35.copyasset()
            36 => asset36.copyasset()
            37 => asset37.copyasset()
            38 => asset38.copyasset()
            39 => asset39.copyasset()

        for j = 1 to 9
            name = switch j
                1 => assetbuff.name

            val = switch j
                2 => assetbuff.beta
                3 => assetbuff.alpha
                4 => assetbuff.sharpe
                5 => assetbuff.sortino
                6 => assetbuff.omega
                7 => assetbuff.zscore
                8 => assetbuff.athdd
                9 => assetbuff.adr
                    
            table.cell(Main, i, j, j == 1 ? name : j > 7 ? str.tostring(math.round(val * 100, j == 8 ? 0 : 2)) + '%' : str.tostring(math.round(val, 2)),
                 text_color = #ffffff, bgcolor = j > 1 ? f_col(j, val) : #000000, text_size = comp ? size.tiny : size.small)

