Coding Investing Tools: Build a Portfolio Tracker in Python

Must read

When you’re coding investing tools, start with a number you can check by hand. Say you own $3,000 of one stock in a $10,000 account. That stock makes up 30% of your account. But if $2,000 of the account is cash, the same stock makes up 37.5% of the money you’ve invested in securities. Both figures are correct. The difference is which dollars you count.

A Python portfolio tracker makes that calculation visible. Give it a spreadsheet of holdings and it can calculate each position’s value, show its share of the account, and draw an allocation chart. Save two dated copies, and you can see why a stock’s weight changed even when you bought no additional shares.

Step 1. Create a Holdings CSV

Create a project folder. Inside it, save the following text as holdings.csv, including the header row. The holdings and prices are fictional, and all values are in U.S. dollars.

holding,quantity,price 
North Stock,30,100 
Broad Equity Fund,80,50 
Bond Fund,12.5,80 
Cash USD,2000,1

When you use your own data, open the holdings or positions section of a dated brokerage statement. It gives you the quantities you owned at the end of that period. Use the activity section if you later need to trace a purchase, dividend, or withdrawal.

CSV column What to enter Common mistake
holding A unique security name or identifier Copying an account subtotal into the file as another holding
quantity Shares or units held on the statement date Rounding 12.5 fund units to 13, adding $40 in this example
price Market price per unit on that date Entering the purchase price or total position value

Represent $2,000 in cash as 2,000 units priced at $1. If a cash sweep balance already includes those dollars, count them once. Enter plain numbers such as 1000.50, without currency symbols or thousands separators.

This version handles fully paid shares, funds, and cash in one reporting currency. Margin debt, short positions, and options require additional valuation rules.

Step 2. Build and Run the Python Portfolio Tracker

The tracker uses two calculations.

  • Position value = quantity × unit price. North Stock’s 30 shares at $100 are worth $3,000.
  • Portfolio weight = position value ÷ total account value × 100. In the sample, $3,000 ÷ $10,000 × 100 gives North a 30% weight.

Save the script below as tracker.py beside holdings.csv. Python’s standard library handles the table and spreadsheet export. Decimal reads fractional quantities and prices directly from the text you entered. Matplotlib is needed only for the chart. The example was tested with Python 3.12.14 and Matplotlib 3.10.8.

import argparse
import csv
from decimal import Decimal, InvalidOperation
from pathlib import Path

parser = argparse.ArgumentParser(description="Calculate portfolio weights from holdings.csv")
parser.add_argument("folder", nargs="?", type=Path, default=Path(__file__).resolve().parent)
parser.add_argument("--chart", action="store_true", help="Also save allocation.png")
args = parser.parse_args()
source = args.folder / "holdings.csv"

if not source.is_file():
parser.exit(1, f"Cannot find {source}. Check the folder and filename.\n")

values = {}
with source.open(encoding="utf-8-sig", newline="") as file:
rows = csv.DictReader(file)
if rows.fieldnames != ["holding", "quantity", "price"]:
raise SystemExit("Use the CSV header: holding,quantity,price")

for row in rows:
line = rows.line_num
name = (row["holding"] or "").strip()
if None in row or not name or name in values:
raise SystemExit(f"Row {line}: check the columns and use a unique holding name.")
try:
quantity = Decimal(row["quantity"] or "")
price = Decimal(row["price"] or "")
except InvalidOperation:
raise SystemExit(f"Row {line}: enter numbers for quantity and price.")
if not quantity.is_finite() or not price.is_finite():
raise SystemExit(f"Row {line}: enter finite numbers.")
if quantity <= 0 or price < 0:
raise SystemExit(f"Row {line}: quantity must be positive and price nonnegative.")
values[name] = quantity * price

total = sum(values.values(), Decimal("0"))
if total == 0:
raise SystemExit("At least one holding must have a positive value.")

ranked = sorted(values, key=values.get, reverse=True)
weights = {name: values[name] * 100 / total for name in ranked}
with (args.folder / "weights.csv").open("w", encoding="utf-8", newline="") as output:
writer = csv.writer(output)
writer.writerow(["holding", "market_value_usd", "weight_pct"])
print(f"{'Holding':<20} {'Value (USD)':>14} {'Weight':>9}")
for name in ranked:
writer.writerow([name, values[name], weights[name]])
print(f"{name:<20} {values[name]:>14,.2f} {weights[name]:>8.2f}%")
print(f"{'Total':<20} {total:>14,.2f} {'100.00%':>9}")

if args.chart:
try:
import matplotlib.pyplot as plt
except ImportError:
raise SystemExit("CSV saved. To create a chart, install matplotlib and run again.")

fig, ax = plt.subplots(figsize=(8, max(3, len(ranked) * 0.5)))
bars = ax.barh(ranked, [float(weights[name]) for name in ranked], color="#246582")
ax.invert_yaxis()
ax.set(xlim=(0, 110), xlabel="Share of portfolio (%)", title="Portfolio weight by holding")
ax.set_xticks(range(0, 101, 20))
ax.bar_label(bars, labels=[f"{weights[name]:.1f}%" for name in ranked], padding=4)
fig.tight_layout()
fig.savefig(args.folder / "allocation.png", dpi=160)
plt.close(fig)

Open a terminal in the project folder and run the following command. If your Python 3 installation uses python3 or the Windows py launcher, substitute that command throughout.

python tracker.py

Check the Output Against the Sample Portfolio

Holding Market value Portfolio weight
Broad Equity Fund $4,000.00 40.00%
North Stock $3,000.00 30.00%
Cash USD $2,000.00 20.00%
Bond Fund $1,000.00 10.00%
Total $10,000.00 100.00%

Open weights.csv in a spreadsheet. The weight_pct column stores percentages as ordinary numbers, so 30 already means 30%. Leave that column in number format. If you prefer to apply spreadsheet percentage formatting, divide the values by 100 first. Otherwise, 30 will display as 3,000%.

Step 3. Create a Portfolio Allocation Chart

Use the same Python installation that ran the tracker. The first command installs Matplotlib. The second generates the chart.

python -m pip install matplotlib 
python tracker.py --chart

Open allocation.png in your project folder. Broad Equity Fund should account for 40% of the sample portfolio, followed by North Stock at 30%.

Step 4. Compare Two Dates and Measure Allocation Drift

Coding Investing with Python portfolio tracker displayed on a laptop, comparing stock prices, investment values, portfolio weights, and asset allocation drift across two dates using interactive financial charts.
Coding Investing Compare portfolio performance across two dates using a Python tracker to monitor stock values investment weights and asset allocation changes

Create two folders beside tracker.py, named 2026-09-30 and 2026-10-30. Put a copy of the sample holdings.csv in each. In the October file, change only North Stock’s price from 100 to 110.

python tracker.py 2026-09-30 
python tracker.py 2026-10-30

Each folder now contains its own weights.csv. Add –chart to either command if you also want an image for that date.

Measure September October Change
North Stock shares 30 30 0
North Stock price $100 $110 +10%
Total account value $10,000 $10,300 +3%
North Stock weight 30.00% 32.04% +2.04 percentage points

North gained $300, so its October weight is $3,300 ÷ $10,300 = 32.04%. Dividing by September’s $10,000 balance would incorrectly give 33%. When a holding changes value, you need to update both its position value and the portfolio total.

If 30% were your chosen target in this example, North would now sit 2.04 percentage points above target. That difference is allocation drift. It can happen without a trade because holdings grow at different rates.

How Much of One Company Do You Own Through a Fund?

The chart tells you which position is largest. To see how much of your money depends on one company, you may also need to look inside your funds. FINRA identifies overlap between individual stocks and fund holdings as one source of concentration risk.

Return to September’s $10,000 account. Suppose North represents 4% of Broad Equity Fund on that date.

Where you own North Calculation Exposure
Directly through North Stock 30 shares × $100 $3,000
Indirectly through Broad Equity Fund $4,000 fund position × 4% $160
Combined exposure through these positions $3,160 ÷ $10,000 31.6% of the account

Keep the $160 out of holdings.csv. It’s already part of the fund’s $4,000 value. Adding it as another position would make a $10,000 account appear to hold $10,160. Your direct stock weight is 30%, while your exposure through the two positions is 31.6%.

Why Your Tracker and Brokerage May Show Different Numbers

Compare the account totals first. If the totals differ, check the statement date, which accounts you included, and the cash balance. If the totals agree, compare the individual holdings. Your statement’s activity section can help trace differences caused by dividends, transfers, and trades.

What you see How to check it
Cash is $40 too high after a dividend If the ending cash balance already includes the $40, remove any separate dividend row.
Fund units rose from 12.5 to 13 A $40 dividend reinvested at $80 buys 0.5 units. Enter the ending quantity and remaining cash.
A stock appears to have lost half its value Check for a 2-for-1 split. With no other price movement, 30 shares at $100 become 60 at $50. Both positions are worth $3,000.
One security appears in two accounts For its combined weight, add the quantities at the same dated price. For separate account views, use distinct labels or folders.
A quote is missing Verify the price and date. Entering zero would erase that holding’s value and inflate the other positions’ weights.
Displayed weights add to 99.99% or 100.01% The terminal rounds each row separately. Use the exported values for further calculations.

For older statements, check what the price provider means by close. Some services publish both the price traded that day and a historical price adjusted for subsequent splits or dividends. Pair the share count on the statement with a price on the same basis. Combining 30 pre-split shares with a $50 post-split price would cut the apparent position value in half.

Conclusion: Coding Investing

Coding investing tools with Python is a practical way to monitor your portfolio, calculate investment values, and understand how your assets are distributed. By building a simple portfolio tracker, you can organize holdings, calculate portfolio weights, create allocation charts, and identify changes in investment exposure over time.

Start with accurate holdings data and basic calculations before adding advanced features such as automated stock prices, performance tracking, and risk analysis. A well-maintained Python portfolio tracker can help you make more informed investment decisions while improving your programming and financial analysis skills.

Coding Investing FAQs

1. Do I Need a Stock Market API to Build a Python Portfolio Tracker?

A dated brokerage statement or holdings export is enough. If you later automate prices, save each quote’s date, currency, and source. Those details let you reproduce last month’s report after market prices have moved on.

2. Can I Track Investments in Multiple Currencies?

Yes. Convert each unit price into one reporting currency first. Ten shares at €20 are worth €200. At a hypothetical exchange rate of $1.10 per euro, enter ten shares at $22 per share for a $220 position in the USD tracker. Keep the dated exchange rate with the original statement.

3. How Do I Separate Investment Gains From New Deposits?

For an account with no transfers of securities, subtract the starting value and cash deposits from the ending value, then add back cash withdrawals. If the account rises from $10,000 to $11,300 after a $1,000 deposit and no withdrawals, $300 of the increase remains after accounting for that deposit.

author avatar
Mercy
Mercy is a passionate writer at Startup Editor, covering business, entrepreneurship, technology, fashion, and legal insights. She delivers well-researched, engaging content that empowers startups and professionals. With expertise in market trends and legal frameworks, Mercy simplifies complex topics, providing actionable insights and strategies for business growth and success.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest article