Blockunity Stablecoin Liquidity (BSL)
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Blockunity & HYVI LDA

//@version=5
indicator("Blockunity Stablecoin Liquidity (BSL)", format = format.volume, overlay = true, scale = scale.left)

//Inputs
display_mode    =   input.string(title = "Display Mode", defval = "Cumulative", options = ["Aggregated", "Cumulative", "Independent"], tooltip = "In Cumulative mode (default), the different capitalizations are displayed one on top of the other with colored bands. The Independent mode also displays the different capitalizations, but detached from each other with labels. Aggregated mode displays a single line, which is the sum of the different capitalizations, varying between green and red depending on the state of this data according to its moving average declared in the 'Aggregated MA Lengh' field.", group = "Global Settings")

USDT_color      =   input(color.new(#0c9b58, 50), title = "", inline = "11", group = "Data Settings")
USDT_input      =   input.bool(true, title = 'Tether (USDT)', inline = "11", tooltip = "Here you can choose whether or not to include Tether data, and configure its display color. Note that in 'Cumulative' display mode, the data is taken into account even if the box is unchecked.", group = "Data Settings")
USDC_color      =   input(color.new(#5085e0, 50), title = "", inline = "12", group = "Data Settings")
USDC_input      =   input.bool(true, title = 'USD Coin (USDC)', inline = "12", tooltip = "Here you can choose whether or not to include USD Coin data, and configure its display color. Note that in 'Cumulative' display mode, the data is taken into account even if the box is unchecked.", group = "Data Settings")
DAI_color       =   input(color.new(#cea315, 50), title = "", inline = "13", group = "Data Settings")
DAI_input       =   input.bool(true, title = 'Dai (DAI)', inline = "13", tooltip = "Here you can choose whether or not to include Dai data, and configure its display color. Note that in 'Cumulative' display mode, the data is taken into account even if the box is unchecked.", group = "Data Settings")
TUSD_color      =   input(color.new(#3639e9, 50), title = "", inline = "14", group = "Data Settings")
TUSD_input      =   input.bool(true, title = 'TrueUSD (TUSD)', inline = "14", tooltip = "Here you can choose whether or not to include TrueUSD data, and configure its display color. Note that in 'Cumulative' display mode, the data is taken into account even if the box is unchecked.", group = "Data Settings")
BUSD_color      =   input(color.new(#8b2dc2, 50), title = "", inline = "15", group = "Data Settings")
BUSD_input      =   input.bool(true, title = 'Binance USD (BUSD)', inline = "15", tooltip = "Here you can choose whether or not to include Binance USD data, and configure its display color. Note that in 'Cumulative' display mode, the data is taken into account even if the box is unchecked.", group = "Data Settings")
FRAX_color      =   input(color.new(#8d8c88, 50), title = "", inline = "16", group = "Data Settings")
FRAX_input      =   input.bool(true, title = 'Frax (FRAX)', inline = "16", tooltip = "Here you can choose whether or not to include Frax data, and configure its display color. Note that in 'Cumulative' display mode, the data is taken into account even if the box is unchecked.", group = "Data Settings")

BSL_ma_len      =   input.int(defval = 100, title = "Aggregated MA Lengh (Days)", tooltip = "Allows you to configure the length (in days) of the moving average, varying the color of the line when the display mode selected is 'Aggregated'. The green color is intended to indicate a positive recovery/upward trend in the overall capitalization of Stablecoins, while a red color shows a decrease/bearish trend.", display = display.none, group = "Aggregated Settings")
showLabels      =   input.bool(defval = true, title = "Display Line Labels", tooltip = "Display or not labels. Works only when 'Display Mode' is set to 'Independent'.", group = "Labels Settings")
labels_offset   =   input.int(defval = 8, title = "Labels Offset", tooltip = "Indicate here the desired offset in the display of the labels. 8 by default.", display = display.none, group = "Labels Settings")

//Table Inputs
tableShow       =   input.bool(defval = true, title = "Display Table", group = "Table Settings")
table_position  =   input.string(title = 'Table Position', defval = 'Top Right', options = ['Top Right', 'Top Center', 'Top Left', 'Middle Right', 'Middle Center', 'Middle Left', 'Bottom Right', 'Bottom Center', 'Bottom Left'], display = display.none, group = "Table Settings")
tableTextSize   =   input.string(title = 'Table Text Size', defval = 'Normal', options = ['Tiny', 'Small', 'Normal', 'Large', 'Huge'], display = display.none, group = "Table Settings")
positiveColor   =   input(color.rgb(8, 153, 129, 30), title = "Positive Color", group = "Table Settings")
negativeColor   =   input(color.rgb(242, 54, 69, 30), title = "Negative Color", group = "Table Settings")
bgTopCellColor  =   input(color.rgb(120, 123, 134, 20), title = "Top Cell Background Color", group = "Table Settings")
bgCellColor     =   input(color.rgb(120, 123, 134, 40), title = "Cell Background Color", group = "Table Settings")
tableTextColor  =   input(color.rgb(255, 255, 255), title = "Text Color", group = "Table Settings")
tableSpace      =   input.int(defval = 2, minval = 0, step = 1, title = "Table Spacing", display = display.none, group = "Table Settings")
script_version  =   input.string(defval = "v1.0", title = "Script Version", options = ["v1.0"], display = display.none, tooltip = "This parameter is only there to indicate the version of the script for support purposes, it cannot be modified.", group = "Version")

//Inputs Override
if display_mode ==  "Cumulative"
    USDT_input  :=  true
    USDC_input  :=  true
    DAI_input   :=  true
    TUSD_input  :=  true
    BUSD_input  :=  true
    FRAX_input  :=  true

//Data
get_data(input, mcap_data) =>
    mcap        =   input ? nz(request.security(mcap_data, "D", close)) : 0

USDT_mcap        =   get_data(USDT_input, "USDT_MARKETCAP")
USDC_mcap        =   get_data(USDC_input, "USDC_MARKETCAP")
DAI_mcap         =   get_data(DAI_input, "DAI_MARKETCAP")
TUSD_mcap        =   get_data(TUSD_input, "CRYPTOCAP:TUSD")
BUSD_mcap        =   get_data(BUSD_input, "BUSD_MARKETCAP")
FRAX_mcap        =   get_data(FRAX_input, "CRYPTOCAP:FRAX")

BSL_sum         =   USDT_mcap + USDC_mcap + DAI_mcap + TUSD_mcap + BUSD_mcap + FRAX_mcap

//Value
BSL_value       =   display_mode == "Aggregated" ? BSL_sum : na

[USDT_value, USDC_value, DAI_value, TUSD_value, BUSD_value, FRAX_value] = switch display_mode
    "Independent"   =>  [USDT_mcap, USDC_mcap, DAI_mcap, TUSD_mcap, BUSD_mcap, FRAX_mcap]
    "Cumulative"    =>  [USDT_mcap, USDT_mcap + USDC_mcap, USDT_mcap + USDC_mcap + DAI_mcap, USDT_mcap + USDC_mcap + DAI_mcap + TUSD_mcap, USDT_mcap + USDC_mcap + DAI_mcap + TUSD_mcap + BUSD_mcap, USDT_mcap + USDC_mcap + DAI_mcap + TUSD_mcap + BUSD_mcap + FRAX_mcap]
    "Aggregated"    =>  [na, na, na, na, na, na]

//MA
BSL_ma          =   request.security(syminfo.tickerid, "D", ta.sma(BSL_sum, BSL_ma_len))
agg_color       =   BSL_sum > BSL_ma ? positiveColor : negativeColor

//Plot
plot_style      =   plot.style_line
plot(BSL_value, style = plot.style_line, linewidth = 2, color = agg_color, title = "Aggregated Stablecoin Marketcap")
USDT_plot       =   plot(USDT_input ? USDT_value    : na,   style = plot_style, linewidth = 2,  color = USDT_color,    title = "Tether (USDT) Marketcap")
USDC_plot       =   plot(USDC_input ? USDC_value    : na,   style = plot_style, linewidth = 2,  color = USDC_color,    title = "USD Coin (USDC) Marketcap")
DAI_plot        =   plot(DAI_input  ? DAI_value     : na,   style = plot_style, linewidth = 2,  color = DAI_color,     title = "Dai (DAI) Marketcap")
TUSD_plot       =   plot(TUSD_input ? TUSD_value    : na,   style = plot_style, linewidth = 2,  color = TUSD_color,    title = "TrueUSD (TUSD) Marketcap")
BUSD_plot       =   plot(BUSD_input ? BUSD_value    : na,   style = plot_style, linewidth = 2,  color = BUSD_color,    title = "Binance USD (BUSD) Marketcap")
FRAX_plot       =   plot(FRAX_input ? FRAX_value    : na,   style = plot_style, linewidth = 2,  color = FRAX_color,    title = "Frax (FRAX) Marketcap")

//Fill
zero_value      =   0
plot0           =   plot(zero_value,    color = color.black,      title = "Zero Value",                   display = display.none)
fill(plot0, USDT_plot,                  color = USDT_color,         title = "Tether (USDT) Marketcap",      display = display_mode == "Cumulative" ? display.all : display.none)
fill(USDT_plot, USDC_plot,              color = USDC_color,         title = "USD Coin (USDC) Marketcap",    display = display_mode == "Cumulative" ? display.all : display.none)
fill(USDC_plot, DAI_plot,               color = DAI_color,          title = "Dai (DAI) Marketcap",          display = display_mode == "Cumulative" ? display.all : display.none)
fill(DAI_plot, TUSD_plot,               color = TUSD_color,         title = "TrueUSD (TUSD) Marketcap",     display = display_mode == "Cumulative" ? display.all : display.none)
fill(TUSD_plot, BUSD_plot,              color = BUSD_color,         title = "Binance USD (BUSD) Marketcap", display = display_mode == "Cumulative" ? display.all : display.none)
fill(BUSD_plot, FRAX_plot,              color = FRAX_color,         title = "Frax (FRAX) Marketcap",        display = display_mode == "Cumulative" ? display.all : display.none)

//Labels
if showLabels and display_mode == "Independent"
    if USDT_mcap > 0
        USDT_label  =   label.new(x = bar_index + labels_offset, y = USDT_value, text = "Tether (USDT)", color = USDT_color, textcolor = tableTextColor)
        label.delete(USDT_label[1])
    if USDC_mcap > 0
        USDC_label  =   label.new(x = bar_index + labels_offset, y = USDC_value, text = "USD Coin (USDC)", color = USDC_color, textcolor = tableTextColor)
        label.delete(USDC_label[1])
    if DAI_mcap > 0
        DAI_label   =   label.new(x = bar_index + labels_offset, y = DAI_value, text = "Dai (DAI)", color = DAI_color, textcolor = tableTextColor)
        label.delete(DAI_label[1])
    if TUSD_mcap > 0
        TUSD_label  =   label.new(x = bar_index + labels_offset, y = TUSD_value, text = "TrueUSD (TUSD)", color = TUSD_color, textcolor = tableTextColor)
        label.delete(TUSD_label[1])
    if BUSD_mcap > 0
        BUSD_label  =   label.new(x = bar_index + labels_offset, y = BUSD_value, text = "Binance USD (BUSD)", color = BUSD_color, textcolor = tableTextColor)
        label.delete(BUSD_label[1])
    if FRAX_mcap > 0
        FRAX_label  =   label.new(x = bar_index + labels_offset, y = FRAX_value, text = "Frax (FRAX)", color = FRAX_color, textcolor = tableTextColor)
        label.delete(FRAX_label[1])

//Table
_table_position =   switch table_position
    "Top Left"      =>  position.top_left
    "Top Center"    =>  position.top_center
    "Top Right"     =>  position.top_right
    "Bottom Left"   =>  position.bottom_left
    "Bottom Center" =>  position.bottom_center
    "Middle Left"   =>  position.middle_left
    "Middle Center" =>  position.middle_center
    "Middle Right"  =>  position.middle_right
    => position.bottom_right

_tableTextSize  =   switch tableTextSize
    "Tiny"          =>  size.tiny
    "Small"         =>  size.small
    "Large"         =>  size.large
    "Huge"          =>  size.huge
    => size.normal

if tableShow == true
    var Table = table.new(_table_position, columns = 3, rows = 8, border_width = tableSpace, border_color = color.new(color.white, 100))
    table.cell(table_id = Table, column = 0, row = 0, bgcolor = bgTopCellColor, text_color = tableTextColor, text_size = _tableTextSize, text = "Stablecoin Liquidity (BSL) by Blockunity")
    table.merge_cells(Table, 0, 0, 2, 0)

    table.cell(table_id = Table, column = 0, row = 1, bgcolor = bgCellColor, text_color = tableTextColor, text_size = _tableTextSize, text = "Aggregated")
    table.cell(table_id = Table, column = 2, row = 1, bgcolor = agg_color, text_color = tableTextColor, text_size = _tableTextSize, text = str.tostring(str.format("{0,number,currency}", BSL_sum)))
    table.merge_cells(Table, 0, 1, 1, 1)

    table.cell(table_id = Table, column = 0, row = 2, bgcolor = USDT_color, text_color = tableTextColor, text_size = _tableTextSize, text = "   ")
    table.cell(table_id = Table, column = 1, row = 2, bgcolor = bgCellColor, text_color = tableTextColor, text_size = _tableTextSize, text = "Tether (USDT)")
    table.cell(table_id = Table, column = 2, row = 2, bgcolor = bgCellColor, text_color = tableTextColor, text_size = _tableTextSize, text = str.tostring(str.format("{0,number,currency}", USDT_mcap)))

    table.cell(table_id = Table, column = 0, row = 3, bgcolor = USDC_color, text_color = tableTextColor, text_size = _tableTextSize, text = "   ")
    table.cell(table_id = Table, column = 1, row = 3, bgcolor = bgCellColor, text_color = tableTextColor, text_size = _tableTextSize, text = "USD Coin (USDC)")
    table.cell(table_id = Table, column = 2, row = 3, bgcolor = bgCellColor, text_color = tableTextColor, text_size = _tableTextSize, text = str.tostring(str.format("{0,number,currency}", USDC_mcap)))

    table.cell(table_id = Table, column = 0, row = 4, bgcolor = DAI_color, text_color = tableTextColor, text_size = _tableTextSize, text = "   ")
    table.cell(table_id = Table, column = 1, row = 4, bgcolor = bgCellColor, text_color = tableTextColor, text_size = _tableTextSize, text = "Dai (DAI)")
    table.cell(table_id = Table, column = 2, row = 4, bgcolor = bgCellColor, text_color = tableTextColor, text_size = _tableTextSize, text = str.tostring(str.format("{0,number,currency}", DAI_mcap)))

    table.cell(table_id = Table, column = 0, row = 5, bgcolor = TUSD_color, text_color = tableTextColor, text_size = _tableTextSize, text = "   ")
    table.cell(table_id = Table, column = 1, row = 5, bgcolor = bgCellColor, text_color = tableTextColor, text_size = _tableTextSize, text = "TrueUSD (TUSD)")
    table.cell(table_id = Table, column = 2, row = 5, bgcolor = bgCellColor, text_color = tableTextColor, text_size = _tableTextSize, text = str.tostring(str.format("{0,number,currency}", TUSD_mcap)))

    table.cell(table_id = Table, column = 0, row = 6, bgcolor = BUSD_color, text_color = tableTextColor, text_size = _tableTextSize, text = "   ")
    table.cell(table_id = Table, column = 1, row = 6, bgcolor = bgCellColor, text_color = tableTextColor, text_size = _tableTextSize, text = "Binance USD (BUSD)")
    table.cell(table_id = Table, column = 2, row = 6, bgcolor = bgCellColor, text_color = tableTextColor, text_size = _tableTextSize, text = str.tostring(str.format("{0,number,currency}", BUSD_mcap)))

    table.cell(table_id = Table, column = 0, row = 7, bgcolor = FRAX_color, text_color = tableTextColor, text_size = _tableTextSize, text = "   ")
    table.cell(table_id = Table, column = 1, row = 7, bgcolor = bgCellColor, text_color = tableTextColor, text_size = _tableTextSize, text = "Frax (FRAX)")
    table.cell(table_id = Table, column = 2, row = 7, bgcolor = bgCellColor, text_color = tableTextColor, text_size = _tableTextSize, text = str.tostring(str.format("{0,number,currency}", FRAX_mcap)))
