Skip to content

Instantly share code, notes, and snippets.

@maczniak
Created December 11, 2023 12:04
Show Gist options
  • Save maczniak/657316af72a7414fb019717c4057ab8d to your computer and use it in GitHub Desktop.
Save maczniak/657316af72a7414fb019717c4057ab8d to your computer and use it in GitHub Desktop.
simple portfolio tracker for TradingView
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © FriendOfTheTrend
// Portfolio Tracker For Stocks & Crypto https://tradingview.com/script/awMm3eHA-Portfolio-Tracker-For-Stocks-Crypto/
// updated by Jeongho Jeon
//@version=5
indicator("Portfolio Tracker", shorttitle="Portfolio Tracker", overlay=true)
// EDIT HERE (START)
// limit: #ticker + #ticker * #gap <= 40
// for example, when #ticker = 10 and #gap = 3 (daily+weekly+monthly), 10 + 10 * 3 <= 40
// when #ticker = 13 and #gap = 2 (daily+monthly), 13 + 13 * 2 <= 40
// when #ticker = 15 and #gap = 1 (weekly), 15 + 15 * 1 <= 40
// when #ticker = 15 and #gap = 2 (daily+monthly), 15 + 15 * 2 > 40 impossible!
[ticker1, size1] = if true
["BATS:AAPL", 10]
[ticker2, size2] = if true
["BINANCE:BTCUSD", 1.2345]
[ticker3, size3] = if true
["BINANCE:ETHUSD", 32.012345678901234567]
[ticker4, size4] = if true
["SUSHISWAP:BAYCWETH_D829DE.USD", 1]
[ticker5, size5] = if true
["OSMOSIS:HUAHUAUSD", 10000000]
[ticker6, size6] = if true
["BATS:TMF", 777]
[ticker7, size7] = if true
["FX_IDC:KRWUSD", 100000000]
[ticker8, size8] = if true
["", 0]
[ticker9, size9] = if true
["", 0]
[ticker10, size10] = if true
["", 0]
numberOfTickers = 7
//Tables On/Off
dataTableOn = input.bool(true, title="Info Table On/Off", group="Info Table")
//Table Positions
bright = position.bottom_right
bleft = position.bottom_left
bcenter = position.bottom_center
tright = position.top_right
tleft = position.top_left
tcenter = position.top_center
mright = position.middle_right
mleft = position.middle_left
mcenter = position.middle_center
tablePosition = input.string(bleft, title="Info Table Position", options=[bright, bleft, bcenter, tright, tleft, tcenter, mright, mleft, mcenter], group="Info Table")
// EDIT HERE (END)
type myticker
string symbol
float size
float price
float price1d
float price1w
float price1m
float value
float percent
float gain1d
color gain1dColor
float gain1w
color gain1wColor
float gain1m
color gain1mColor
tickers = array.new<myticker>()
// You cannot unroll statements into a loop because ticker name must have "simple string" (i.e., constant) type.
// And you cannot request security inside "if" statement.
if 1 <= numberOfTickers
t = myticker.new(ticker1, size1)
array.push(tickers, t)
t.price := request.security(ticker1, "", close, barmerge.gaps_off, ignore_invalid_symbol=true)
t.price1d := request.security(ticker1, "D", close[1], barmerge.gaps_off, ignore_invalid_symbol=true)
t.price1w := request.security(ticker1, "W", close[1], barmerge.gaps_off, ignore_invalid_symbol=true)
t.price1m := request.security(ticker1, "M", close[1], barmerge.gaps_off, ignore_invalid_symbol=true)
if 2 <= numberOfTickers
t = myticker.new(ticker2, size2)
array.push(tickers, t)
t.price := request.security(ticker2, "", close, barmerge.gaps_off, ignore_invalid_symbol=true)
t.price1d := request.security(ticker2, "D", close[1], barmerge.gaps_off, ignore_invalid_symbol=true)
t.price1w := request.security(ticker2, "W", close[1], barmerge.gaps_off, ignore_invalid_symbol=true)
t.price1m := request.security(ticker2, "M", close[1], barmerge.gaps_off, ignore_invalid_symbol=true)
if 3 <= numberOfTickers
t = myticker.new(ticker3, size3)
array.push(tickers, t)
t.price := request.security(ticker3, "", close, barmerge.gaps_off, ignore_invalid_symbol=true)
t.price1d := request.security(ticker3, "D", close[1], barmerge.gaps_off, ignore_invalid_symbol=true)
t.price1w := request.security(ticker3, "W", close[1], barmerge.gaps_off, ignore_invalid_symbol=true)
t.price1m := request.security(ticker3, "M", close[1], barmerge.gaps_off, ignore_invalid_symbol=true)
if 4 <= numberOfTickers
t = myticker.new(ticker4, size4)
array.push(tickers, t)
t.price := request.security(ticker4, "", close, barmerge.gaps_off, ignore_invalid_symbol=true)
t.price1d := request.security(ticker4, "D", close[1], barmerge.gaps_off, ignore_invalid_symbol=true)
t.price1w := request.security(ticker4, "W", close[1], barmerge.gaps_off, ignore_invalid_symbol=true)
t.price1m := request.security(ticker4, "M", close[1], barmerge.gaps_off, ignore_invalid_symbol=true)
if 5 <= numberOfTickers
t = myticker.new(ticker5, size5)
array.push(tickers, t)
t.price := request.security(ticker5, "", close, barmerge.gaps_off, ignore_invalid_symbol=true)
t.price1d := request.security(ticker5, "D", close[1], barmerge.gaps_off, ignore_invalid_symbol=true)
t.price1w := request.security(ticker5, "W", close[1], barmerge.gaps_off, ignore_invalid_symbol=true)
t.price1m := request.security(ticker5, "M", close[1], barmerge.gaps_off, ignore_invalid_symbol=true)
if 6 <= numberOfTickers
t = myticker.new(ticker6, size6)
array.push(tickers, t)
t.price := request.security(ticker6, "", close, barmerge.gaps_off, ignore_invalid_symbol=true)
t.price1d := request.security(ticker6, "D", close[1], barmerge.gaps_off, ignore_invalid_symbol=true)
t.price1w := request.security(ticker6, "W", close[1], barmerge.gaps_off, ignore_invalid_symbol=true)
t.price1m := request.security(ticker6, "M", close[1], barmerge.gaps_off, ignore_invalid_symbol=true)
if 7 <= numberOfTickers
t = myticker.new(ticker7, size7)
array.push(tickers, t)
t.price := request.security(ticker7, "", close[0], barmerge.gaps_off, ignore_invalid_symbol=true)
t.price1d := request.security(ticker7, "D", close[1], barmerge.gaps_off, ignore_invalid_symbol=true)
t.price1w := request.security(ticker7, "W", close[1], barmerge.gaps_off, ignore_invalid_symbol=true)
t.price1m := request.security(ticker7, "M", close[1], barmerge.gaps_off, ignore_invalid_symbol=true)
if 8 <= numberOfTickers
t = myticker.new(ticker8, size8)
array.push(tickers, t)
t.price := request.security(ticker8, "", close, barmerge.gaps_off, ignore_invalid_symbol=true)
t.price1d := request.security(ticker8, "D", close[1], barmerge.gaps_off, ignore_invalid_symbol=true)
t.price1w := request.security(ticker8, "W", close[1], barmerge.gaps_off, ignore_invalid_symbol=true)
t.price1m := request.security(ticker8, "M", close[1], barmerge.gaps_off, ignore_invalid_symbol=true)
if 9 <= numberOfTickers
t = myticker.new(ticker9, size9)
array.push(tickers, t)
t.price := request.security(ticker9, "", close, barmerge.gaps_off, ignore_invalid_symbol=true)
t.price1d := request.security(ticker9, "D", close[1], barmerge.gaps_off, ignore_invalid_symbol=true)
t.price1w := request.security(ticker9, "W", close[1], barmerge.gaps_off, ignore_invalid_symbol=true)
t.price1m := request.security(ticker9, "M", close[1], barmerge.gaps_off, ignore_invalid_symbol=true)
if 10 <= numberOfTickers
t = myticker.new(ticker10, size10)
array.push(tickers, t)
t.price := request.security(ticker10, "", close, barmerge.gaps_off, ignore_invalid_symbol=true)
t.price1d := request.security(ticker10, "D", close[1], barmerge.gaps_off, ignore_invalid_symbol=true)
t.price1w := request.security(ticker10, "W", close[1], barmerge.gaps_off, ignore_invalid_symbol=true)
t.price1m := request.security(ticker10, "M", close[1], barmerge.gaps_off, ignore_invalid_symbol=true)
float usdkrw = 0 // request.security("USDKRW", "", close, barmerge.gaps_off, ignore_invalid_symbol=true)
float currentCapital = 0
float yesterdayCapital = 0
float previousWeekCapital = 0
float previousMonthCapital = 0
for t in tickers
t.value := t.price * t.size
t.gain1d := (t.price - t.price1d) / t.price1d
t.gain1dColor := t.price > t.price1d ? color.green : t.price < t.price1d ? color.red : color.blue
t.gain1w := (t.price - t.price1w) / t.price1w
t.gain1wColor := t.price > t.price1w ? color.green : t.price < t.price1w ? color.red : color.blue
t.gain1m := (t.price - t.price1m) / t.price1m
t.gain1mColor := t.price > t.price1m ? color.green : t.price < t.price1m ? color.red : color.blue
currentCapital += t.value
yesterdayCapital += t.price1d * t.size
previousWeekCapital += t.price1w * t.size
previousMonthCapital += t.price1m * t.size
for t in tickers
t.percent := t.value / currentCapital
// custom
if str.endswith(t.symbol, "KRWUSD")
usdkrw := 1 / t.price
t.price := usdkrw
capitalGain1d = (currentCapital - yesterdayCapital) / yesterdayCapital
capitalGain1dColor = currentCapital > yesterdayCapital ? color.green : currentCapital < yesterdayCapital ? color.red : color.blue
capitalGain1w = (currentCapital - previousWeekCapital) / previousWeekCapital
capitalGain1wColor = currentCapital > previousWeekCapital ? color.green : currentCapital < previousWeekCapital ? color.red : color.blue
capitalGain1m = (currentCapital - previousMonthCapital) / previousMonthCapital
capitalGain1mColor = currentCapital > previousMonthCapital ? color.green : currentCapital < previousMonthCapital ? color.red : color.blue
//Plot Data To Table
dataTable = table.new(tablePosition, columns=8, rows=numberOfTickers+2, bgcolor=color.blue, frame_color=color.white, frame_width=1, border_color=color.white, border_width=1)
if dataTableOn and barstate.islast
table.cell(table_id=dataTable, column=0, row=0, text="Asset Name", height=0, text_color=color.white, text_halign=text.align_left, text_valign=text.align_center, bgcolor=color.navy)
table.cell(table_id=dataTable, column=1, row=0, text="Weight", height=0, text_color=color.white, text_halign=text.align_left, text_valign=text.align_center, bgcolor=color.navy)
table.cell(table_id=dataTable, column=2, row=0, text="$ Value", height=0, text_color=color.white, text_halign=text.align_left, text_valign=text.align_center, bgcolor=color.navy)
table.cell(table_id=dataTable, column=3, row=0, text="HM", height=0, text_color=color.white, text_halign=text.align_left, text_valign=text.align_center, bgcolor=color.navy)
table.cell(table_id=dataTable, column=4, row=0, text="Price", height=0, text_color=color.white, text_halign=text.align_left, text_valign=text.align_center, bgcolor=color.navy)
table.cell(table_id=dataTable, column=5, row=0, text="Today", height=0, text_color=color.white, text_halign=text.align_left, text_valign=text.align_center, bgcolor=color.navy)
table.cell(table_id=dataTable, column=6, row=0, text="Week", height=0, text_color=color.white, text_halign=text.align_left, text_valign=text.align_center, bgcolor=color.navy)
table.cell(table_id=dataTable, column=7, row=0, text="Month", height=0, text_color=color.white, text_halign=text.align_left, text_valign=text.align_center, bgcolor=color.navy)
row = 1
for t in tickers
table.cell(table_id=dataTable, column=0, row=row, text=array.get(str.split(array.get(str.split(t.symbol, ":"), 1), "_"), 0), height=0, text_color=color.white, text_halign=text.align_left, text_valign=text.align_center)
table.cell(table_id=dataTable, column=1, row=row, text=str.tostring(t.percent*100, format.percent), height=0, text_color=color.white, text_halign=text.align_left, text_valign=text.align_center)
table.cell(table_id=dataTable, column=2, row=row, text="$" + str.tostring(t.value, "#.##"), height=0, text_color=color.white, text_halign=text.align_left, text_valign=text.align_center, bgcolor=color.green)
table.cell(table_id=dataTable, column=3, row=row, text=str.tostring(t.value*usdkrw/100000000, "#.##"), height=0, text_color=color.white, text_halign=text.align_left, text_valign=text.align_center, bgcolor=color.green)
table.cell(table_id=dataTable, column=4, row=row, text=str.tostring(t.price), height=0, text_color=color.white, text_halign=text.align_left, text_valign=text.align_center, bgcolor=color.green)
table.cell(table_id=dataTable, column=5, row=row, text=str.tostring(math.abs(t.gain1d)*100, "#.##") + "%", height=0, text_color=color.white, text_halign=text.align_left, text_valign=text.align_center, bgcolor=t.gain1dColor)
table.cell(table_id=dataTable, column=6, row=row, text=str.tostring(math.abs(t.gain1w)*100, "#.##") + "%", height=0, text_color=color.white, text_halign=text.align_left, text_valign=text.align_center, bgcolor=t.gain1wColor)
table.cell(table_id=dataTable, column=7, row=row, text=str.tostring(math.abs(t.gain1m)*100, "#.##") + "%", height=0, text_color=color.white, text_halign=text.align_left, text_valign=text.align_center, bgcolor=t.gain1mColor)
row += 1
table.cell(table_id=dataTable, column=0, row=row, text="Total", height=0, text_color=color.white, text_halign=text.align_left, text_valign=text.align_center, bgcolor=color.navy)
table.cell(table_id=dataTable, column=2, row=row, text="$" + str.tostring(currentCapital, "#.##"), height=0, text_color=color.white, text_halign=text.align_left, text_valign=text.align_center, bgcolor=color.green)
table.cell(table_id=dataTable, column=3, row=row, text=str.tostring(currentCapital*usdkrw/100000000, "#.##"), height=0, text_color=color.white, text_halign=text.align_left, text_valign=text.align_center, bgcolor=color.green)
table.cell(table_id=dataTable, column=5, row=row, text=str.tostring(math.abs(capitalGain1d)*100, "#.##") + "%", height=0, text_color=color.white, text_halign=text.align_left, text_valign=text.align_center, bgcolor=capitalGain1dColor)
table.cell(table_id=dataTable, column=6, row=row, text=str.tostring(math.abs(capitalGain1w)*100, "#.##") + "%", height=0, text_color=color.white, text_halign=text.align_left, text_valign=text.align_center, bgcolor=capitalGain1wColor)
table.cell(table_id=dataTable, column=7, row=row, text=str.tostring(math.abs(capitalGain1m)*100, "#.##") + "%", height=0, text_color=color.white, text_halign=text.align_left, text_valign=text.align_center, bgcolor=capitalGain1mColor)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment