redk-portfolio-tracker-table-version.pine
Copy
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © RedKTrader
//@version=5
indicator(title='RedK_Portfolio Tracker [Table Version]', shorttitle='Redk_PTable v7.0', overlay=true, scale=scale.none, format=format.volume)
// v7 change log
// optimize code & declaration and calculation of variables
//=============================================================================================================================================
Get_qDiv(_symbol) =>
qDiv = request.dividends(_symbol, dividends.gross, ignore_invalid_symbol=true, currency= currency.USD)
na(qDiv) ? 0 : qDiv
//=============================================================================================================================================
Get_price(_sym) =>
_price = request.security(_sym, timeframe.period, close, barmerge.gaps_off)
//=============================================================================================================================================
ShowDiv = input.bool(title='Show Dividends? ', defval=false, inline='settings')
TargetSet = input.bool(title='Set Target?', defval=false, inline='settings')
TargetValue = input.float(title='', defval=10000, inline='settings')
//================================================================================================================================================
p_1 = input.bool(title='Pos #01 ', defval=true, inline='#1', group='Portfolio Details:')
sym_1 = input.symbol(title='', defval='MSFT', inline='#1', group='Portfolio Details:')
qty_1 = input.float(title='Qty', defval=1000, inline='#1', group='Portfolio Details:')
cost_1 = input.float(title='Cost', defval=100, inline='#1', group='Portfolio Details:')
var val_1 = 0.0, var tvalue_1 = 0.0, var tcost_1 = 0.0, var PosPnL_1 = 0.0
if p_1
val_1 := Get_price(sym_1)
tvalue_1 := val_1 * qty_1
tcost_1 := cost_1 * qty_1
PosPnL_1 := tvalue_1 - tcost_1
//=======================================================================================
p_2 = input.bool(title='Pos #02 ', defval=true, inline='#2', group='Portfolio Details:')
sym_2 = input.symbol(title='', defval='AAPL', inline='#2', group='Portfolio Details:')
qty_2 = input.float(title='Qty', defval=1000, inline='#2', group='Portfolio Details:')
cost_2 = input.float(title='Cost', defval=100, inline='#2', group='Portfolio Details:')
var val_2 = 0.0, var tvalue_2 = 0.0, var tcost_2 = 0.0, var PosPnL_2 = 0.0
if p_2
val_2 := Get_price(sym_2)
tvalue_2 := val_2 * qty_2
tcost_2 := cost_2 * qty_2
PosPnL_2 := tvalue_2 - tcost_2
//=======================================================================================
p_3 = input.bool(title='Pos #03 ', defval=true, inline='#3', group='Portfolio Details:')
sym_3 = input.symbol(title='', defval='INTC', inline='#3', group='Portfolio Details:')
qty_3 = input.float(title='Qty', defval=1000, inline='#3', group='Portfolio Details:')
cost_3 = input.float(title='Cost', defval=40, inline='#3', group='Portfolio Details:')
var val_3 = 0.0, var tvalue_3 = 0.0, var tcost_3 = 0.0, var PosPnL_3 = 0.0
if p_3
val_3 := Get_price(sym_3)
tvalue_3 := val_3 * qty_3
tcost_3 := cost_3 * qty_3
PosPnL_3 := tvalue_3 - tcost_3
//=======================================================================================
p_4 = input.bool(title='Pos #04 ', defval=false, inline='#4', group='Portfolio Details:')
sym_4 = input.symbol(title='', defval='MSFT', inline='#4', group='Portfolio Details:')
qty_4 = input.float(title='Qty', defval=100, inline='#4', group='Portfolio Details:')
cost_4 = input.float(title='Cost', defval=50, inline='#4', group='Portfolio Details:')
var val_4 = 0.0, var tvalue_4 = 0.0, var tcost_4 = 0.0, var PosPnL_4 = 0.0
if p_4
val_4 := Get_price(sym_4)
tvalue_4 := val_4 * qty_4
tcost_4 := cost_4 * qty_4
PosPnL_4 := tvalue_4 - tcost_4
//=======================================================================================
p_5 = input.bool(title='Pos #05 ', defval=false, inline='#5', group='Portfolio Details:')
sym_5 = input.symbol(title='', defval='MSFT', inline='#5', group='Portfolio Details:')
qty_5 = input.float(title='Qty', defval=100, inline='#5', group='Portfolio Details:')
cost_5 = input.float(title='Cost', defval=100, inline='#5', group='Portfolio Details:')
var val_5 = 0.0, var tvalue_5 = 0.0, var tcost_5 = 0.0, var PosPnL_5 = 0.0
if p_5
val_5 := Get_price(sym_5)
tvalue_5 := val_5 * qty_5
tcost_5 := cost_5 * qty_5
PosPnL_5 := tvalue_5 - tcost_5
//=======================================================================================
p_6 = input.bool(title='Pos #06 ', defval=false, inline='#6', group='Portfolio Details:')
sym_6 = input.symbol(title='', defval='MSFT', inline='#6', group='Portfolio Details:')
qty_6 = input.float(title='Qty', defval=100, inline='#6', group='Portfolio Details:')
cost_6 = input.float(title='Cost', defval=100, inline='#6', group='Portfolio Details:')
var val_6 = 0.0, var tvalue_6 = 0.0, var tcost_6 = 0.0, var PosPnL_6 = 0.0
if p_6
val_6 := Get_price(sym_6)
tvalue_6 := val_6 * qty_6
tcost_6 := cost_6 * qty_6
PosPnL_6 := tvalue_6 - tcost_6
//=======================================================================================
p_7 = input.bool(title='Pos #07 ', defval=false, inline='#7', group='Portfolio Details:')
sym_7 = input.symbol(title='', defval='MSFT', inline='#7', group='Portfolio Details:')
qty_7 = input.float(title='Qty', defval=100, inline='#7', group='Portfolio Details:')
cost_7 = input.float(title='Cost', defval=100, inline='#7', group='Portfolio Details:')
var val_7 = 0.0, var tvalue_7 = 0.0, var tcost_7 = 0.0, var PosPnL_7 = 0.0
if p_7
val_7 := Get_price(sym_7)
tvalue_7 := val_7 * qty_7
tcost_7 := cost_7 * qty_7
PosPnL_7 := tvalue_7 - tcost_7
//=======================================================================================
p_8 = input.bool(title='Pos #08 ', defval=false, inline='#8', group='Portfolio Details:')
sym_8 = input.symbol(title='', defval='MSFT', inline='#8', group='Portfolio Details:')
qty_8 = input.float(title='Qty', defval=100, inline='#8', group='Portfolio Details:')
cost_8 = input.float(title='Cost', defval=100, inline='#8', group='Portfolio Details:')
var val_8 = 0.0, var tvalue_8 = 0.0, var tcost_8 = 0.0, var PosPnL_8 = 0.0
if p_8
val_8 := Get_price(sym_8)
tvalue_8 := val_8 * qty_8
tcost_8 := cost_8 * qty_8
PosPnL_8 := tvalue_8 - tcost_8
//=======================================================================================
p_9 = input.bool(title='Pos #09 ', defval=false, inline='#9', group='Portfolio Details:')
sym_9 = input.symbol(title='', defval='MSFT', inline='#9', group='Portfolio Details:')
qty_9 = input.float(title='Qty', defval=10, inline='#9', group='Portfolio Details:')
cost_9 = input.float(title='Cost', defval=100, inline='#9', group='Portfolio Details:')
var val_9 = 0.0, var tvalue_9 = 0.0, var tcost_9 = 0.0, var PosPnL_9 = 0.0
if p_9
val_9 := Get_price(sym_9)
tvalue_9 := val_9 * qty_9
tcost_9 := cost_9 * qty_9
PosPnL_9 := tvalue_9 - tcost_9
//=======================================================================================
p_10 = input.bool(title='Pos #10', defval=false, inline='#10', group='Portfolio Details:')
sym_10 = input.symbol(title='', defval='MSFT', inline='#10', group='Portfolio Details:')
qty_10 = input.float(title='Qty', defval=10, inline='#10', group='Portfolio Details:')
cost_10 = input.float(title='Cost', defval=100, inline='#10', group='Portfolio Details:')
var val_10 = 0.0, var tvalue_10 = 0.0, var tcost_10 = 0.0, var PosPnL_10 = 0.0
if p_10
val_10 := Get_price(sym_10)
tvalue_10 := val_10 * qty_10
tcost_10 := cost_10 * qty_10
PosPnL_10 := tvalue_10 - tcost_10
//=======================================================================================
c_0 = input.bool(title='Cash (Avaiable to trade)', defval=true, inline='Cash', group='Portfolio Details:')
cash_0 = input.float(title='', defval=10000, inline='Cash', group='Portfolio Details:')
var Cash = c_0 ? cash_0 : 0
//================================================================================================================================================================
var numpos = (p_1 ? 1 : 0) + (p_2 ? 1 : 0) + (p_3 ? 1 : 0) + (p_4 ? 1 : 0) + (p_5 ? 1 : 0) + (p_6 ? 1 : 0) + (p_7 ? 1 : 0) + (p_8 ? 1 : 0) + (p_9 ? 1 : 0) + (p_10 ? 1 : 0)
TotalValue = tvalue_1 + tvalue_2 + tvalue_3 + tvalue_4 + tvalue_5 + tvalue_6 + tvalue_7 + tvalue_8 + tvalue_9 + tvalue_10
TotalPortfolio = TotalValue + Cash
var TotalCost = tcost_1 + tcost_2 + tcost_3 + tcost_4 + tcost_5 + tcost_6 + tcost_7 + tcost_8 + tcost_9 + tcost_10
var InitCapital = TotalCost + Cash
RetOnPositions = PosPnL_1 + PosPnL_2 + PosPnL_3 + PosPnL_4 + PosPnL_5 + PosPnL_6 + PosPnL_7 + PosPnL_8 + PosPnL_9 + PosPnL_10
RetOnPos_pct = RetOnPositions / TotalCost
TotalPnL = TotalPortfolio - InitCapital
PortfolioChange = ta.change(TotalPortfolio)
PortfolioUp = PortfolioChange > 0
PnLChange = ta.change(TotalPnL)
PnLUp = PnLChange > 0
// ===========================================================================
var c_up = color.new(color.blue, 50)
var c_dn = color.new(color.orange, 50)
plot(TotalPortfolio, 'TotalPortfolio', color=PortfolioUp ? c_up : c_dn, linewidth=3, style=plot.style_stepline, display=display.none)
plot(TotalPnL, 'Total P&L', color=PnLUp ? color.green : color.red, linewidth=3, style=plot.style_columns, display=display.none)
// ==============================================================================================================================================================
// Prepare Table
numformat = '$ #,###' //"#.##"
pctformat = '#.## %'
//n = bar_index
NL = '\n'
arrowup = ' ↗ ↗'
arrowdn = ' ↘ ↘'
var txt_sz1 = size.tiny
var txt_sz2 = size.small
var txt_sz3 = size.normal
var txt_sz4 = size.large
var txt_sz5 = size.huge
var txt_sz0 = size.auto
var tbl_pos1 = position.top_right
var tbl_pos2 = position.middle_right
var tbl_pos3 = position.bottom_right
ctable = input.color(title='Table Color', defval=#1111ff, inline='Table', group='Table:')
cframe = input.color(title='Frame Color', defval=#ffeb3b, inline='Table', group='Table:')
i_position = input.string(title='Table Position:', defval=tbl_pos3, options=[tbl_pos1, tbl_pos2, tbl_pos3], inline='Table', group='Table:')
i_text_size = input.string(title='Text Size:', defval=txt_sz0, options=[txt_sz0, txt_sz1, txt_sz2, txt_sz3, txt_sz4, txt_sz5], inline='Text', group='Table:')
ctext = input.color(title='Text color', defval=#ffffff, inline='Text', group='Table:')
ctitle = input.color(title='Title Row', defval=#000000, inline='BG', group='Backgrounds:')
v_up = input.color(title='Up BG', defval=#2962ff, inline='BG', group='Backgrounds:')
v_dn = input.color(title='Down BG', defval=#d32f2f, inline='BG', group='Backgrounds:')
var NoValue = int(na) // nice trick to pass no value for label rows
var PTable = table.new(position=i_position, columns=2, rows=23, bgcolor=ctable, frame_color=cframe, frame_width=2, border_color=ctitle, border_width=2)
// fill table
// =====================================================================================================================
f_FillRow(_table, _row, _label, _value, _vFormat) =>
TitleRow = na(_value) ? true : false
l_color = TitleRow ? ctitle : ctable
v_color = TitleRow ? ctitle : _value >= 0 ? v_up : v_dn
_ValueText = TitleRow ? '' : str.tostring(_value, _vFormat)
table.cell(_table, 0, _row, _label, bgcolor=l_color, text_color=ctext, text_size=i_text_size, text_halign=TitleRow ? text.align_right : text.align_left)
table.cell(_table, 1, _row, _ValueText, bgcolor=v_color, text_color=ctext, text_size=i_text_size, text_halign=text.align_right)
// =====================================================================================================================
var i = -1
if barstate.islast
// ***********************************************************************************************************************************************************
// one-time calc moved to this section
cash_pct = Cash / TotalPortfolio
PnLpct = TotalPnL / InitCapital // Note: no divide by 100 as the percentage is built into the number formatting
Gainpct = PnLChange / TotalPortfolio[1]
Total_qDiv = 0.0, qDiv_Yield = 0.0
if ShowDiv
qdiv_1 = p_1 ? Get_qDiv(sym_1) * qty_1 : 0
qdiv_2 = p_2 ? Get_qDiv(sym_2) * qty_2 : 0
qdiv_3 = p_3 ? Get_qDiv(sym_3) * qty_3 : 0
qdiv_4 = p_4 ? Get_qDiv(sym_4) * qty_4 : 0
qdiv_5 = p_5 ? Get_qDiv(sym_5) * qty_5 : 0
qdiv_6 = p_6 ? Get_qDiv(sym_6) * qty_6 : 0
qdiv_7 = p_7 ? Get_qDiv(sym_7) * qty_7 : 0
qdiv_8 = p_8 ? Get_qDiv(sym_8) * qty_8 : 0
qdiv_9 = p_9 ? Get_qDiv(sym_9) * qty_9 : 0
qdiv_10 = p_10 ? Get_qDiv(sym_10) * qty_10 : 0
Total_qDiv := qdiv_1 + qdiv_2 + qdiv_3 + qdiv_4 + qdiv_5 + qdiv_6 + qdiv_7 + qdiv_8 + qdiv_9 + qdiv_10
qDiv_Yield := Total_qDiv / InitCapital
// Target stuff
Target = TargetSet ? TargetValue : 0
Target_pct = Target / InitCapital
PnL_v_Tgt_pct = TargetSet ? TotalPnL / Target : 0 //watch out for Div/0 -- this is normal PnL percent of target
PnL_v2_Tgt_pct = TargetSet ? TotalPnL / Target - 1 : 0 // This is "variance to target" - so it only shows 0 when we actually hit the target
// ***********************************************************************************************************************************************************
i += 1, f_FillRow(PTable, i, 'Summary', NoValue, '')
i += 1, f_FillRow(PTable, i, '# Active Positions ', numpos, '')
i += 1, f_FillRow(PTable, i, 'Cost of Positions ', TotalCost, numformat)
i += 1, f_FillRow(PTable, i, 'Cash in Account ', Cash, numformat)
i += 1, f_FillRow(PTable, i, 'Initial Capital ', InitCapital, numformat)
i += 1, f_FillRow(PTable, i, 'Performance', NoValue, '')
i += 1, f_FillRow(PTable, i, 'Value of Positions ', TotalValue, numformat)
i += 1, f_FillRow(PTable, i, 'Return on Positions (PnL $) ', RetOnPositions, numformat)
i += 1, f_FillRow(PTable, i, 'Return on Positions % ', RetOnPos_pct, pctformat)
i += 1, f_FillRow(PTable, i, 'Total Potfolio (NetWorth) ', TotalPortfolio, numformat)
i += 1, f_FillRow(PTable, i, 'PnL % of Potfolio ', PnLpct, pctformat)
i += 1, f_FillRow(PTable, i, 'Cash % of Portfolio ', cash_pct, pctformat)
i += 1, f_FillRow(PTable, i, 'Last Bar', NoValue, '')
i += 1, f_FillRow(PTable, i, '$ Gain ', PnLChange, numformat)
i += 1, f_FillRow(PTable, i, '% Gain ', Gainpct, pctformat)
if ShowDiv and Total_qDiv > 0
i += 1, f_FillRow(PTable, i, 'Dividends', NoValue, '')
i += 1, f_FillRow(PTable, i, '$ Qtrly Dividends ', Total_qDiv, numformat)
i += 1, f_FillRow(PTable, i, '% Qtrly Div Yield ', qDiv_Yield, pctformat)
if TargetSet and Target > 0
i += 1, f_FillRow(PTable, i, 'Target Tracker', NoValue, '')
i += 1, f_FillRow(PTable, i, 'Portfolio Target', Target, numformat)
i += 1, f_FillRow(PTable, i, 'Target % of Capital ', Target_pct, pctformat)
i += 1, f_FillRow(PTable, i, 'PnL % of Target ', PnL_v_Tgt_pct, pctformat)
i += 1, f_FillRow(PTable, i, 'PnL % var to Target ', PnL_v2_Tgt_pct, pctformat)
//=============================================================================================================================================
Show all 308 lines