Portfolio Heat
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Amphibiantrading

//@version=5
indicator('Portfolio Heat', overlay = true)

//----------settings----------//
acct        = input.float(100000., 'Account Size', confirm = true)
view        = input.string('Detailed View', 'Detail Options', ['Detailed View', 'Summary'])
levels      = input.bool(false, 'Show Levels On Holdings')
entCol      = input.color(color.green, 'Entry Color', inline = '0')
stopCol     = input.color(color.red, 'Stop Color', inline = '0')
yPos        = input.string('Bottom', 'Table Position ', options = ['Top', 'Middle', 'Bottom'], inline = '1')
xPos        = input.string('Center', ' ', options = ['Right','Center', 'Left'], inline = '1')
headCol     = input.color(color.rgb(0, 111, 202), 'Header Background Color')
headTxtCol  = input.color(color.white, 'Header Text Color')
listCol     = input.color(color.gray, 'Symbols Background Color')
txtDataCol  = input.color(color.white, 'Data Text Color')
txtTotalCol = input.color(color.red, 'Total Text Color')
txtSize     = input.string('Normal', 'Table Size', ['Tiny', 'Small', 'Normal', 'Large'])

var g0      = 'Symbol 1'
useSym0     = input.bool(true, ' ', inline = '1', group = g0, confirm = true)
sym0        = input.symbol('CELH', ' ', inline = '1', group = g0, confirm = true)
shares0     = input.int(0, 'Shares', inline = '1', group = g0, confirm = true)
entry0      = input.float(0.0, 'Entry', inline =  '2', group = g0, confirm = true)
stop0       = input.float(0.0, 'Stop', inline =  '2', group = g0, confirm = true)

var g1      = 'Symbol 2'
useSym1     = input.bool(false, '', inline =  '1', group = g1)
sym1        = input.symbol('AAPL', ' ', inline = '1', group = g1)
shares1     = input.int(0, 'Shares', inline = '1', group = g1)
entry1      = input.float(0.0, 'Entry', inline =  '2', group = g1)
stop1       = input.float(0.0, 'Stop', inline =  '2', group = g1)

var g2      = 'Symbol 3'
useSym2     = input.bool(false, '', inline =  '1', group = g2)
sym2        = input.symbol('TSLA', ' ', inline = '1', group = g2)
shares2     = input.int(0, 'Shares', inline = '1', group = g2)
entry2      = input.float(0.0, 'Entry', inline =  '2', group = g2)
stop2       = input.float(0.0, 'Stop', inline =  '2', group = g2)

var g3      = 'Symbol 4'
useSym3     = input.bool(false, '', inline =  '1', group = g3)
sym3        = input.symbol('NVDA', ' ', inline = '1', group = g3)
shares3     = input.int(0, 'Shares', inline = '1', group = g3)
entry3      = input.float(0.0, 'Entry', inline =  '2', group = g3)
stop3       = input.float(0.0, 'Stop', inline =  '2', group = g3)

var g4      = 'Symbol 5'
useSym4     = input.bool(false, '', inline =  '1', group = g4)
sym4        = input.symbol('GOOGL', ' ', inline = '1', group = g4)
shares4     = input.int(0, 'Shares', inline = '1', group = g4)
entry4      = input.float(0.0, 'Entry', inline =  '2', group = g4)
stop4       = input.float(0.0, 'Stop', inline =  '2', group = g4)

var g5      = 'Symbol 6'
useSym5     = input.bool(false, '', inline =  '1', group = g5)
sym5        = input.symbol('MSFT', ' ', inline = '1', group = g5)
shares5     = input.int(0, 'Shares', inline = '1', group = g5)
entry5      = input.float(0.0, 'Entry', inline =  '2', group = g5)
stop5       = input.float(0.0, 'Stop', inline =  '2', group = g5)

var g6      = 'Symbol 7'
useSym6     = input.bool(false, '', inline =  '1', group = g6)
sym6        = input.symbol('AMD', ' ', inline = '1', group = g6)
shares6     = input.int(0, 'Shares', inline = '1', group = g6)
entry6      = input.float(0.0, 'Entry', inline =  '2', group = g6)
stop6       = input.float(0.0, 'Stop', inline =  '2', group = g6)

var g7      = 'Symbol 8'
useSym7     = input.bool(false, '', inline =  '1', group = g7)
sym7        = input.symbol('NFLX', ' ', inline = '1', group = g7)
shares7     = input.int(0, 'Shares', inline = '1', group = g7)
entry7      = input.float(0.0, 'Entry', inline =  '2', group = g7)
stop7       = input.float(0.0, 'Stop', inline =  '2', group = g7)

var g8      = 'Symbol 9'
useSym8     = input.bool(false, '', inline =  '1', group = g8)
sym8        = input.symbol('NFLX', ' ', inline = '1', group = g8)
shares8     = input.int(0, 'Shares', inline = '1', group = g8)
entry8      = input.float(0.0, 'Entry', inline =  '2', group = g8)
stop8       = input.float(0.0, 'Stop', inline =  '2', group = g8)

var g9      = 'Symbol 10'
useSym9     = input.bool(false, '', inline =  '1', group = g9)
sym9        = input.symbol('NFLX', ' ', inline = '1', group = g9)
shares9     = input.int(0, 'Shares', inline = '1', group = g9)
entry9      = input.float(0.0, 'Entry', inline =  '2', group = g9)
stop9       = input.float(0.0, 'Stop', inline =  '2', group = g9)

if not useSym0
    entry0  := 0.0
    shares0 := 0
    stop0   := 0.0
if not useSym1
    entry1  := 0.0
    shares1 := 0
    stop1   := 0.0
if not useSym2
    entry2  := 0.0
    shares2 := 0
    stop2   := 0.0
if not useSym3
    entry3  := 0.0
    shares3 := 0
    stop3   := 0.0
if not useSym4
    entry4  := 0.0
    shares4 := 0
    stop4   := 0.0
if not useSym5
    entry5  := 0.0
    shares5 := 0
    stop5   := 0.0
if not useSym6
    entry6  := 0.0
    shares6 := 0
    stop6   := 0.0
if not useSym7
    entry7  := 0.0
    shares7 := 0
    stop7   := 0.0
if not useSym8
    entry8  := 0.0
    shares8 := 0
    stop8   := 0.0
if not useSym9
    entry9  := 0.0
    shares9 := 0
    stop9   := 0.0

//----------variables----------//
var table data = table.new(str.lower(yPos) + '_' + str.lower(xPos), 12, 4, color.new(color.white,100),
     color.new(color.white,100), 2, color.new(color.white,100),2)
var line entryLine = na
var line stopLine = na

//----------functions & methods----------//
getPrice (sym)=>
    request.security(sym, 'D', close)

calcRisk(curr, ent, sto, shrs)=> 
    risk    = (curr - sto) * shrs
    perRisk = (risk / acct) * 100
    capRisk = (ent - sto) * shrs
    [risk, perRisk, capRisk]

fsplit(a)=>
    test  = str.split(a, ":")

tableCell(col,row, txt, txtcolor, bgcolor, size)=>
    data.cell(col,row, txt, text_color = txtcolor, bgcolor = bgcolor, text_size = size)

tblSize = switch txtSize
    'Tiny'   => size.tiny
    'Normal' => size.normal
    'Small'  => size.small
    'Large'  => size.large

//----------calculations----------//
close0 = getPrice(sym0)
close1 = getPrice(sym1)
close2 = getPrice(sym2)
close3 = getPrice(sym3)
close4 = getPrice(sym4)
close5 = getPrice(sym5)
close6 = getPrice(sym6)
close7 = getPrice(sym7)
close8 = getPrice(sym8)
close9 = getPrice(sym9)

[dr0, pr0, cr0] = calcRisk(close0, entry0, stop0, shares0)
[dr1, pr1, cr1] = calcRisk(close1, entry1, stop1, shares1)
[dr2, pr2, cr2] = calcRisk(close2, entry2, stop2, shares2)
[dr3, pr3, cr3] = calcRisk(close3, entry3,stop3, shares3)
[dr4, pr4, cr4] = calcRisk(close4, entry4,stop4, shares4)
[dr5, pr5, cr5] = calcRisk(close5, entry5,stop5, shares5)
[dr6, pr6, cr6] = calcRisk(close6, entry6,stop6, shares6)
[dr7, pr7, cr7] = calcRisk(close7, entry7,stop7, shares7)
[dr8, pr8, cr8] = calcRisk(close8, entry8,stop8, shares8)
[dr9, pr9, cr9] = calcRisk(close9, entry9,stop9, shares9)

//----------data arrays----------//
drArr   = array.from(dr0,dr1,dr2,dr3,dr4,dr5,dr6,dr7,dr8,dr9)
prArr   = array.from(pr0,pr1,pr2,pr3,pr4,pr5,pr6,pr7,pr8,pr9)
crArr   = array.from(cr0,cr1,cr2,cr3,cr4,cr5,cr6,cr7,cr8,cr9)
symArr  = array.from(sym0,sym1,sym2,sym3,sym4,sym5,sym6,sym7,sym8,sym9)
useArr  = array.from(useSym0,useSym1,useSym2,useSym3,useSym4,useSym5,useSym6,useSym7,useSym8,useSym9)

totalRisk   = drArr.sum()
perRisk     = (totalRisk / acct) * 100
capRisk     = crArr.sum()

//----------create the data table----------//
if barstate.islast
    data.cell(0,1, 'Open Dollar Risk', text_color = headTxtCol, text_halign = text.align_right, bgcolor = headCol, text_size = tblSize)
    data.cell(0,2, 'Open % of Portfolio Risk', text_color = headTxtCol, text_halign = text.align_right, bgcolor = headCol, text_size = tblSize)
    data.cell(11,1, '$' + str.tostring(totalRisk, '#,###.##'), text_color =txtTotalCol, text_size = tblSize)
    data.cell(11,2, str.tostring(perRisk, '#.##') + '%', text_color = txtTotalCol, text_size = tblSize)
    if view == 'Detailed View'
        data.cell(0,0, 'Symbol', text_color = headTxtCol, text_halign = text.align_right, bgcolor = headCol, text_size = tblSize)
        data.cell(11,0, 'Totals', text_color = headTxtCol, bgcolor = headCol, text_size = tblSize)
        data.cell(0,3, 'Starting Capital Risk', text_color = headTxtCol, text_halign = text.align_right, bgcolor = headCol, text_size = tblSize)
        data.cell(11,3, '$' + str.tostring(capRisk, format.mintick), text_color = txtTotalCol, text_size = tblSize)
        for i = 0 to useArr.size()-1
            if useArr.get(i) == true
                symbol = fsplit(symArr.get(i)).get(1)
                tableCell(i+1,0, symbol, headTxtCol, listCol, tblSize)
                tableCell(i+1,1, '$' + str.tostring(drArr.get(i), '#,###.##'), txtDataCol, color.new(color.white,100), tblSize)
                tableCell(i+1,2, str.tostring(prArr.get(i), '#.##') + "%", txtDataCol, color.new(color.white,100), tblSize)
                tableCell(i+1,3, '$' + str.tostring(crArr.get(i), '#,###.##'), txtDataCol, color.new(color.white,100), tblSize)


if levels and (syminfo.ticker == fsplit(sym0).get(1) and useSym0)
    entryLine := line.new(bar_index[1], entry0, bar_index, entry0, color = entCol, extend = extend.both)
    stopLine := line.new(bar_index[1], stop0, bar_index, stop0, color = stopCol, extend = extend.both)
else if levels and (syminfo.ticker == fsplit(sym1).get(1) and useSym1)
    entryLine := line.new(bar_index[1], entry1, bar_index, entry1, color = entCol, extend = extend.both)
    stopLine := line.new(bar_index[1], stop1, bar_index, stop1, color = stopCol, extend = extend.both)
else if levels and (syminfo.ticker == fsplit(sym2).get(1) and useSym2)
    entryLine := line.new(bar_index[1], entry2, bar_index, entry2, color = entCol, extend = extend.both)
    stopLine := line.new(bar_index[1], stop2, bar_index, stop2, color = stopCol, extend = extend.both)
else if levels and (syminfo.ticker == fsplit(sym3).get(1) and useSym3)
    entryLine := line.new(bar_index[1], entry3, bar_index, entry3, color = entCol, extend = extend.both)
    stopLine := line.new(bar_index[1], stop3, bar_index, stop3, color = stopCol, extend = extend.both)
else if levels and (syminfo.ticker == fsplit(sym4).get(1) and useSym4)
    entryLine := line.new(bar_index[1], entry4, bar_index, entry4, color = entCol, extend = extend.both)
    stopLine := line.new(bar_index[1], stop4, bar_index, stop4, color = stopCol, extend = extend.both)
else if levels and (syminfo.ticker == fsplit(sym5).get(1) and useSym5)
    entryLine := line.new(bar_index[1], entry5, bar_index, entry5, color = entCol, extend = extend.both)
    stopLine := line.new(bar_index[1], stop5, bar_index, stop5, color = stopCol, extend = extend.both)
else if levels and (syminfo.ticker == fsplit(sym6).get(1) and useSym6)
    entryLine := line.new(bar_index[1], entry6, bar_index, entry6, color = entCol, extend = extend.both)
    stopLine := line.new(bar_index[1], stop6, bar_index, stop6, color = stopCol, extend = extend.both)
else if levels and (syminfo.ticker == fsplit(sym7).get(1) and useSym7)
    entryLine := line.new(bar_index[1], entry7, bar_index, entry7, color = entCol, extend = extend.both)
    stopLine := line.new(bar_index[1], stop7, bar_index, stop7, color = stopCol, extend = extend.both)
else if levels and (syminfo.ticker == fsplit(sym8).get(1) and useSym8)
    entryLine := line.new(bar_index[1], entry8, bar_index, entry8, color = entCol, extend = extend.both)
    stopLine := line.new(bar_index[1], stop8, bar_index, stop8, color = stopCol, extend = extend.both)
else if levels and (syminfo.ticker == fsplit(sym9).get(1) and useSym9)
    entryLine := line.new(bar_index[1], entry9, bar_index, entry9, color = entCol, extend = extend.both)
    stopLine := line.new(bar_index[1], stop9, bar_index, stop9, color = stopCol, extend = extend.both)