2022-05-07
If you are searching for a simple way to keep track of your personal investment portfolio and you are savvy on the command line you can check out the portfolio management tool that I have written in Python: finance
Example output, plotted with matplotlib
:
For installation and usage instructions please refer to the README of the project.
Let's start at the beginning: I am very passionate about personal finance and investing. However, as much as I like researching the markets, I absolutely do not want to spend more time than necessary micro-managing my portfolio or keeping track of every little change.
If you search for existing portfolio managers on the internet, you find a good amount of high-quality apps and projects that help you keep track of almost everything you want in a personal finance tool, e.g., Portfolio Performace (Website) (Github).
While Portfolio Performance is great and powerful (it really is!), it simply does not work for me. Setting everything up and creating entries for assets, asset classes and transactions can take multiple hours. Personally, I find this too much of a hassle. While it may work really well for some people, it really does not work for me.
Online tools such as a simple Google Sheet offer almost everything I want (e.g. Google Finance live quotes). However, they leave me somewhat uncomfortable from a privacy standpoint, since my personal portfolio balance is stored online in the cloud. I prefer my financial data balance to remain offline if possible.
Also: FUN! Why not take the time to learn something new and build my own tool from scratch?
Here are my requirements for a personal investment portfolio management tool that suits my needs best:
I settled for this structure for the portfolio file:
Name | Ticker | Asset Class | Amount |
---|---|---|---|
Stock A | AAA.AA | Stocks | 1 |
Bond B | BBB.BB | Bonds | 2 |
Crypto C | CRYPTO-CURR | Crypto | 0.5 |
With this structure as a data model, users only need to add a single line for each asset and only ever update the last column (amount) if the balance of the portfolio changes.
Tickers are important for querying market quotas and are pretty easy
to look up online. I decided to use pandas
and
get_quote_yahoo
from pandas_datareader
to get
live market prices from yahoo finance.
Maintaining a healthy asset allocation and diversification across asset classes is a must for me, so the data model should also include the type of asset class for each asset in the file.
The data itself can be stored in a simple .csv
file,
looking something like this:
Name,Ticker,AC,Amount
S&P 500,SPY,S,2
US Treasury 20+yr,TLT,B,4
Commodities,GSG,C,3
Gold,GLD,G,1
Bitcoin,BTC-USD,CRYPTO,0.01
Cash,-,CASH,200
Getting the current price of an asset via yahoo finance is fairly
simple using pandas_datareader.get_quote_yahoo()
:
from pandas_datareader.data import get_quote_yahoo
= "AAPL" # ticker for Apple Inc.
ticker = get_quote_yahoo(ticker)["price"][0] currPrice
The pandas
python library makes it really easy to print
out the overall balances of the portfolio in a well-formed and pleasing
format. After getting quotes for each asset, we only need to update the
balance for that asset by multiplying it with the amount stored in the
data file.
def getQuotes(data):
= data["Ticker"]
tickers
print("Getting current prices from Yahoo Finance...")
= []
balances
for i in range(0, len(tickers)):
= data["AC"][i]
ac # If Asset Class is cash, then get amount only
if ac == "CASH":
"Amount"][i])
balances.append(data[else:
try:
= get_quote_yahoo(tickers[i])["price"][0]
currPrice = data["Amount"][i]
amount round(currPrice*amount, 2))
balances.append(except Exception:
print("No quote for this ticker")
"Balance"] = balances
data[return data
The overall result looks like this:
================================================================
Name Ticker AC Amount Balance
0 NASDAQ 100 QQQ S 50.0 15462.50
1 S&P 500 SPY S 350.0 143969.00
2 US Treasury 20+yr TLT B 750.0 85252.50
3 Commodities GSG C 1000.0 24370.00
4 Gold GLD G 150.0 26313.00
5 Bitcoin BTC-USD CRYPTO 0.5 17987.15
6 Ether ETH-USD CRYPTO 2.5 6384.83
7 Cash - CASH 15000.0 15000.00
Your total balance is: $334738.98
================================================================
Note: This is example data and does not reflect my actual balance and/or allocation.
Users can use the third-party encryption utility gpg
to
encrypt their data file. In that case, the data stays encrypted at rest
and users are prompted for their gpg passphrase (if they have one) for
their default gpg identity. This allows for secure sync between
platforms via, e.g., git. Decrypted values are never written to
disk.
In order to transparently edit encrypted data files, I recommend vim-gnupg for editing your data file.
I might consider adding performance tracking in the future, but this will require some form of persistant datastore of balances and transactions (buy/sell/etc.). Since this will likely add significant complexity, you should be better off using something like Portfolio Performance.