Portfolio Tracker [Anan]
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Mohamed3nan
/////////////////////////////////////////////////
//        /\                                   //
//       /  \     _ __     __ _   _ __         //
//      / /\ \   | '_ \   / _` | | '_ \        //
//     / ____ \  | | | | | (_| | | | | |       //
//    /_/    \_\ |_| |_|  \__,_| |_| |_|       //
/////////////////////////////////////////////////

//@version=5
// ---------------------------------------------------------------------------------------------- //

indicator('Portfolio Tracker [Anan]', 'Portfolio Tracker [Anan]', true)
group_1 = 'Asset / Quantity / Avg. Buy/Sell Price'
use1 = input.bool(true, '', inline='1', group=group_1)
sym1 = input.symbol('BINANCE:BTCUSDT', '', inline='1', group=group_1)
qty1 = input.float(1, 'QTY', inline='1', group=group_1)
price1 = input.float(10000, 'Price', inline='1', group=group_1)
use2 = input.bool(false, '', inline='2', group=group_1)
sym2 = input.symbol('', '', inline='2', group=group_1)
qty2 = input.float(0, 'QTY', inline='2', group=group_1)
price2 = input.float(0, 'Price', inline='2', group=group_1)
use3 = input.bool(false, '', inline='3', group=group_1)
sym3 = input.symbol('', '', inline='3', group=group_1)
qty3 = input.float(0, 'QTY', inline='3', group=group_1)
price3 = input.float(0, 'Price', inline='3', group=group_1)
use4 = input.bool(false, '', inline='4', group=group_1)
sym4 = input.symbol('', '', inline='4', group=group_1)
qty4 = input.float(0, 'QTY', inline='4', group=group_1)
price4 = input.float(0, 'Price', inline='4', group=group_1)
use5 = input.bool(false, '', inline='5', group=group_1)
sym5 = input.symbol('', '', inline='5', group=group_1)
qty5 = input.float(0, 'QTY', inline='5', group=group_1)
price5 = input.float(0, 'Price', inline='5', group=group_1)
use6 = input.bool(false, '', inline='6', group=group_1)
sym6 = input.symbol('', '', inline='6', group=group_1)
qty6 = input.float(0, 'QTY', inline='6', group=group_1)
price6 = input.float(0, 'Price', inline='6', group=group_1)
use7 = input.bool(false, '', inline='7', group=group_1)
sym7 = input.symbol('', '', inline='7', group=group_1)
qty7 = input.float(0, 'QTY', inline='7', group=group_1)
price7 = input.float(0, 'Price', inline='7', group=group_1)
use8 = input.bool(false, '', inline='8', group=group_1)
sym8 = input.symbol('', '', inline='8', group=group_1)
qty8 = input.float(0, 'QTY', inline='8', group=group_1)
price8 = input.float(0, 'Price', inline='8', group=group_1)
use9 = input.bool(false, '', inline='9', group=group_1)
sym9 = input.symbol('', '', inline='9', group=group_1)
qty9 = input.float(0, 'QTY', inline='9', group=group_1)
price9 = input.float(0, 'Price', inline='9', group=group_1)
use10 = input.bool(false, '', inline='10', group=group_1)
sym10 = input.symbol('', '', inline='10', group=group_1)
qty10 = input.float(0, 'QTY', inline='10', group=group_1)
price10 = input.float(0, 'Price', inline='10', group=group_1)

group_table = 'Table Position & Size & Colors'
string tableYpos = input.string('top', '↕', inline='01', group=group_table, options=['top', 'middle', 'bottom'])
string tableXpos = input.string('right', '↔', inline='01', group=group_table, options=['left', 'center', 'right'], tooltip='Position on the chart.')
int tableRowHeight = input.int(0, '|', inline='02', group=group_table, minval=0, maxval=100)
int tableColWidth = input.int(0, '—', inline='02', group=group_table, minval=0, maxval=100, tooltip='0-100. Use 0 to auto-size height and width.')
string textSize_ = input.string('Small', 'Table Text Size', options=['Auto', 'Tiny', 'Small', 'Normal', 'Large', 'Huge'], group=group_table)
string textSize = textSize_ == 'Auto' ? size.auto : textSize_ == 'Tiny' ? size.tiny : textSize_ == 'Small' ? size.small : textSize_ == 'Normal' ? size.normal : textSize_ == 'Large' ? size.large : size.huge
color row_col = input.color(color.blue, 'Headers', inline='03', group=group_table)
color col_col = input.color(color.blue, ' ', inline='03', group=group_table)
color poscol = input.color(color.green, 'Profit/Loss', inline='04', group=group_table)
color neutralcolor = input.color(color.gray, '', inline='04', group=group_table)
color negcol = input.color(color.red, '', inline='04', group=group_table)
// ---------------------------------------------------------------------------------------------- //

var table anan = table.new(tableYpos + '_' + tableXpos, 8, 11, border_width=2)
table.cell(anan, 0, 0, 'Asset', text_color=col_col, bgcolor=color.new(col_col, 80), text_size=textSize, width=tableColWidth, height=tableRowHeight)
table.cell(anan, 1, 0, 'Price (24H%)', text_color=col_col, bgcolor=color.new(col_col, 80), text_size=textSize, width=tableColWidth, height=tableRowHeight)
table.cell(anan, 2, 0, 'Holdings', text_color=col_col, bgcolor=color.new(col_col, 80), text_size=textSize, width=tableColWidth, height=tableRowHeight)
table.cell(anan, 3, 0, 'Current Value', text_color=col_col, bgcolor=color.new(col_col, 80), text_size=textSize, width=tableColWidth, height=tableRowHeight)
table.cell(anan, 4, 0, 'Avg. Price', text_color=col_col, bgcolor=color.new(col_col, 80), text_size=textSize, width=tableColWidth, height=tableRowHeight)
table.cell(anan, 5, 0, 'Cost Value', text_color=col_col, bgcolor=color.new(col_col, 80), text_size=textSize, width=tableColWidth, height=tableRowHeight)
table.cell(anan, 6, 0, 'Profit/Loss', text_color=col_col, bgcolor=color.new(col_col, 80), text_size=textSize, width=tableColWidth, height=tableRowHeight)
table.cell(anan, 7, 0, 'Profit/Loss %', text_color=col_col, bgcolor=color.new(col_col, 80), text_size=textSize, width=tableColWidth, height=tableRowHeight)

// ---------------------------------------------------------------------------------------------- //
getCurPrice(sym) =>
    request.security(sym, '12M', close)

getROC(sym) =>
    request.security(sym, '1D', ta.roc(close, 1))

renderTable(cell, use, sym, qty, price) =>
    curPrice = getCurPrice(sym)
    roc = getROC(sym)
    if use
        table.cell(anan, 0, cell, sym, text_color=row_col, bgcolor=color.new(row_col, 80), text_size=textSize, width=tableColWidth, height=tableRowHeight)
        table.cell(anan, 1, cell, str.tostring(curPrice) + ' (' + str.tostring(roc, '#.##') + '%)', text_color=roc > 0 ? poscol : roc < 0 ? negcol : neutralcolor, bgcolor=color.new(roc > 0 ? poscol : roc < 0 ? negcol : neutralcolor, 80), text_size=textSize, width=tableColWidth, height=tableRowHeight)
        table.cell(anan, 2, cell, str.tostring(qty), text_color=poscol, bgcolor=color.new(poscol, 80), text_size=textSize, width=tableColWidth, height=tableRowHeight)
        table.cell(anan, 3, cell, str.tostring(curPrice * qty), text_color=curPrice * qty > price * qty ? poscol : curPrice * qty < price * qty ? negcol : neutralcolor, bgcolor=color.new(curPrice * qty > price * qty ? poscol : curPrice * qty < price * qty ? negcol : neutralcolor, 80), text_size=textSize, width=tableColWidth, height=tableRowHeight)
        table.cell(anan, 4, cell, str.tostring(price), text_color=curPrice > price ? poscol : curPrice < price ? negcol : neutralcolor, bgcolor=color.new(curPrice > price ? poscol : curPrice < price ? negcol : neutralcolor, 80), text_size=textSize, width=tableColWidth, height=tableRowHeight)
        table.cell(anan, 5, cell, str.tostring(price * qty), text_color=curPrice * qty > price * qty ? poscol : curPrice * qty < price * qty ? negcol : neutralcolor, bgcolor=color.new(curPrice * qty > price * qty ? poscol : curPrice * qty < price * qty ? negcol : neutralcolor, 80), text_size=textSize, width=tableColWidth, height=tableRowHeight)
        table.cell(anan, 6, cell, str.tostring(curPrice * qty - price * qty), text_color=curPrice * qty - price * qty > 0 ? poscol : curPrice * qty - price * qty < 0 ? negcol : neutralcolor, bgcolor=color.new(curPrice * qty - price * qty > 0 ? poscol : curPrice * qty - price * qty < 0 ? negcol : neutralcolor, 80), text_size=textSize, width=tableColWidth, height=tableRowHeight)
        table.cell(anan, 7, cell, str.tostring((curPrice * qty - price * qty) / (price * qty) * 100, '#.##') + '%', text_color=curPrice * qty - price * qty > 0 ? poscol : curPrice * qty - price * qty < 0 ? negcol : neutralcolor, bgcolor=color.new(curPrice * qty - price * qty > 0 ? poscol : curPrice * qty - price * qty < 0 ? negcol : neutralcolor, 80), text_size=textSize, width=tableColWidth, height=tableRowHeight)

// ---------------------------------------------------------------------------------------------- //
renderTable(1, use1, sym1, qty1, price1)
renderTable(2, use2, sym2, qty2, price2)
renderTable(3, use3, sym3, qty3, price3)
renderTable(4, use4, sym4, qty4, price4)
renderTable(5, use5, sym5, qty5, price5)
renderTable(6, use6, sym6, qty6, price6)
renderTable(7, use7, sym7, qty7, price7)
renderTable(8, use8, sym8, qty8, price8)
renderTable(9, use9, sym9, qty9, price9)
renderTable(10, use10, sym10, qty10, price10)
// ---------------------------------------------------------------------------------------------- //

