A comprehensive portfolio tracking system built with Python and Streamlit for tracking Indian stocks, US stocks, mutual funds, and crypto/DeFi positions with monthly snapshots, real-time pricing, and detailed analytics.
- Screenshots
- Features
- Key Highlights
- How It Works
- Tech Stack
- Quick Start
- Testing the Application
- Project Structure
- Database Schema
- Supported File Formats
- Development
- Troubleshooting
- Future Enhancements
β οΈ DISCLAIMER: The portfolio values shown in these screenshots are completely fictional dummy data generated for demonstration purposes. I'm still broke as hell π. If I actually had βΉ3M in investments, I wouldn't be writing README files at 2 AM. These numbers are about as real as my chances of retiring early. Please don't report me to the tax authorities - my real portfolio is just tears and regret.
Main dashboard showing portfolio value, asset allocation, and key metrics
Performance tracking with detailed charts and trends
Best and worst performing holdings at a glance
Indian stocks holdings with real-time valuation
US stocks portfolio with automatic USD to INR conversion
Mutual funds tracking with NAV updates
All holdings in one unified view
Easy upload interface for monthly portfolio data
Export your portfolio data to Excel
- Dashboard: Portfolio overview with KPIs, charts, and performance metrics
- Holdings: Detailed view of Indian stocks, US stocks, and mutual funds
- Trends: Historical portfolio value tracking with 6-month visualization
- Upload: Easy monthly data import from Excel files (supports 3 asset types)
- Export: Generate comprehensive Excel reports
- Real-time Pricing: Integration with Yahoo Finance for live stock prices
- Currency Conversion: Automatic USD to INR conversion for US stocks
- Benchmarking: Compare against Nifty 50 and Sensex
- Smart Merge: Upload new data without overwriting existing holdings
- Crypto/DeFi Tracking: Live wallet scanning for DeFi positions across Ethereum, Base, Arbitrum, Optimism, Polygon
- Multi-Protocol Support: Aave, Compound, Uniswap, Lido, and more via crypto-portfolio-tracker
- Wallet Management: Add, remove, and manage multiple Ethereum wallet addresses
- Backend: Python 3.11+
- Framework: Streamlit
- Database: SQLite with SQLAlchemy ORM
- Package Manager: uv
- Charts: Plotly
- Deployment: Docker
β¨ Multi-Asset Support: Track Indian stocks, US stocks, and mutual funds in one place π± Smart Currency Conversion: Automatic real-time USD to INR conversion for US stocks π Rich Analytics: 6-month trends, top performers, asset allocation, and benchmark comparison π Smart Merge: Upload new data without overwriting existing holdings π€ Export Ready: Generate comprehensive Excel reports with all portfolio data π― Privacy First: Local database, no cloud dependencies, your data stays with you π DeFi Integration: Track Aave, Compound, Lido positions with live on-chain scanning
When you upload US stocks data from DriveWealth:
- Real-time Exchange Rate: Fetches current USD/INR rate from Yahoo Finance (
USDINR=Xticker) - Automatic Conversion: Converts all USD values (prices, invested value, current value) to INR during parsing
- Caching: Rate is cached for 5 minutes to reduce API calls
- Fallback: Uses βΉ83.00/USD if API is unavailable
- Consistent Display: All portfolio values displayed in INR across the application
Example: MSFT stock at $108.51 with exchange rate 90.17 INR/USD β Stored as βΉ9,784.35
When uploading to an existing snapshot date:
- Selective Deletion: Only deletes holdings of the asset types you're uploading
- Preservation: Keeps holdings of other asset types intact
- Merge: Combines existing holdings with new uploads
- Recalculation: Updates snapshot summary with all combined holdings
Example Scenario:
- Existing data (Jan 10): 25 Indian stocks, 13 Mutual funds, 12 US stocks
- Upload: New US stocks file (15 holdings)
- Result: 25 Indian stocks β, 13 Mutual funds β, 15 US stocks (updated) = 53 total holdings
- Python 3.11 or higher
- uv package manager
- Docker (optional, for containerized deployment)
To enable crypto portfolio tracking, you need:
-
Infura Project ID (free tier available):
- Sign up at infura.io
- Create a new project
- Copy the Project ID
-
Etherscan API Keys (free, for contract ABIs):
- Etherscan - Ethereum mainnet
- Basescan - Base chain
- Arbiscan - Arbitrum
- Optimistic Etherscan - Optimism
- Polygonscan - Polygon
-
Environment Variables (add to
.env):WEB3_INFURA_PROJECT_ID=your_infura_project_id ETHERSCAN_API_KEY=your_etherscan_api_key BASESCAN_API_KEY=your_basescan_api_key ARBISCAN_API_KEY=your_arbiscan_api_key OPTIMISTIC_ETHERSCAN_API_KEY=your_optimistic_etherscan_api_key POLYGONSCAN_API_KEY=your_polygonscan_api_key
Module Used: crypto-portfolio-tracker - A Python library for scanning DeFi positions across multiple chains and protocols.
You can use these public wallet addresses to test the crypto tracking feature:
| Address | Description | Protocols |
|---|---|---|
0xd8da6bf26964af9d7eed9e03e53415d37aa96045 |
Vitalik Buterin (vitalik.eth) | Aave V3, various tokens |
0x9fC3dc011b461664c835F2527fffb1169b3C213e |
Ethereum Foundation Multisig | Aave, Spark, Compound |
0xBFbeD8717AEB318Eb7cE20913dd7563287c474bA |
DeFi Example Wallet | Various DeFi positions |
Note: Scanning takes 2-3 minutes as it checks multiple chains (Ethereum, Base, Arbitrum, Optimism, Polygon) in parallel.
-
Clone the repository:
git clone <repository-url> cd investment-tracker-v2
-
Install dependencies:
uv sync
-
Run the application:
uv run streamlit run app/Home.py
-
Open in browser: Visit http://localhost:8501
-
Build and run with Docker Compose:
docker-compose up --build
-
Access the app: Visit http://localhost:8501
-
Stop the container:
docker-compose down
For testing or demo purposes, you can generate realistic sample portfolio data:
.venv/bin/python generate_sample_data.pyThis creates:
- 6 monthly snapshots (July 2025 - December 2025)
- 15-20 holdings per month across all asset types
- Realistic stock symbols (RELIANCE, TCS, AAPL, MSFT, etc.)
- Portfolio values ranging from βΉ2.3M to βΉ3.1M
- Growth trends and realistic P&L percentages
Crypto Sample Data (when crypto module is enabled):
- 4-6 DeFi positions across multiple protocols
- Example positions: Aave lending, Lido staking, Compound supply, Uniswap LP
- Total crypto value: ~$25,000-30,000 USD (~βΉ20-25L INR)
Navigate to the Upload page and import your portfolio data:
- Upload Excel files for three asset types:
- Indian Stocks: Broker holdings statement (.xlsx)
- Mutual Funds: MF holdings statement (.xlsx)
- US Stocks: DriveWealth Profit-Loss statement (.xlsx)
- Preview the parsed data in expandable sections
- Click "Save to Database" to store the snapshot
- Smart merge: Upload to existing dates without overwriting other asset types
Data Management Options:
- Delete specific snapshots by month
- Clear all data (with confirmation)
- View recent upload history
Go to the Dashboard page to see your portfolio overview:
Dashboard Features:
- Portfolio value, invested amount, and total P&L
- Asset allocation pie chart (Indian stocks, US stocks, mutual funds)
- 6-month portfolio value trend
- Monthly growth comparison
Performance Tracking:
- Historical value trends over time
- Invested vs current value comparison
- Month-over-month growth visualization
Visit the Holdings page to analyze your investments:
- All Indian stock holdings with live prices
- P&L tracking per stock
- Sortable by value, returns, or symbol
- US stock holdings with automatic USD to INR conversion
- Real-time exchange rate application
- Symbol-based tracking (AAPL, MSFT, NVDA, etc.)
- All mutual fund holdings
- NAV tracking and XIRR calculation
- Scheme-wise performance
- Unified view of all assets
- Filter and sort across asset types
- Export-ready comprehensive table
investment-tracker-v2/
βββ app/
β βββ Home.py # Streamlit main page
β βββ pages/
β βββ 1_Dashboard.py # Dashboard with charts
β βββ 2_Holdings.py # Detailed holdings view
β βββ 3_Upload.py # File upload interface
β βββ 4_Trends.py # Portfolio trends & analytics
β βββ 5_Export.py # Export to Excel
β βββ 6_Crypto.py # Crypto wallet management & scanning
βββ src/
β βββ database/
β β βββ models.py # SQLAlchemy models
β β βββ repository.py # Data access layer
β βββ parsers/
β β βββ stocks.py # Indian stocks parser
β β βββ mutual_funds.py # Mutual funds parser
β β βββ us_stocks.py # US stocks parser (DriveWealth)
β βββ services/
β β βββ portfolio.py # Portfolio calculations
β β βββ pricing.py # Yahoo Finance integration
β β βββ benchmarks.py # Nifty/Sensex data
β β βββ crypto.py # Crypto/DeFi position scanning
β βββ exports/
β βββ excel_exporter.py # Excel export functionality
βββ screenshots/ # README screenshots
βββ data/
β βββ uploads/ # Uploaded Excel files
β βββ exports/ # Generated reports
β βββ portfolio.db # SQLite database
βββ Dockerfile
βββ docker-compose.yml
βββ pyproject.toml
βββ ape-config.yaml # Ape framework chain configuration
βββ DATA_FORMAT_SPECIFICATION.md # Detailed file format guide
Always verify no sensitive data is staged:
git status
git diff --stagedIf you accidentally staged sensitive files:
git reset HEAD <file>Stores individual holdings per snapshot for all asset types:
| Column | Type | Description |
|---|---|---|
id |
Integer | Primary key |
snapshot_date |
DateTime | Date of the snapshot |
type |
Enum | Asset type: stock, us_stock, mutual_fund, crypto |
name |
String | Asset name |
symbol |
String | Ticker symbol (stocks only) |
isin |
String | ISIN code (Indian stocks & MF) |
units |
Float | Quantity/units held |
avg_price |
Float | Average purchase price (INR) |
invested_value |
Float | Total cost basis (INR) |
current_price |
Float | Current price per unit (INR) |
current_value |
Float | Current market value (INR) |
unrealized_pl |
Float | Profit/Loss amount (INR) |
unrealized_pl_pct |
Float | P&L percentage |
Monthly portfolio summaries with aggregated metrics:
| Column | Type | Description |
|---|---|---|
snapshot_date |
DateTime | Unique date identifier (primary key) |
total_value |
Float | Total portfolio value (INR) |
stocks_value |
Float | Indian stocks value (INR) |
mf_value |
Float | Mutual funds value (INR) |
us_stocks_value |
Float | US stocks value (INR) |
total_invested |
Float | Total cost basis (INR) |
total_pl |
Float | Total P&L (INR) |
total_pl_pct |
Float | Total P&L percentage |
benchmark_nifty |
Float | NIFTY 50 index value |
benchmark_sensex |
Float | SENSEX index value |
crypto_value |
Float | Crypto/DeFi positions value (INR) |
Audit trail of all file uploads:
| Column | Type | Description |
|---|---|---|
id |
Integer | Primary key |
upload_date |
DateTime | Upload timestamp |
snapshot_date |
DateTime | Data snapshot date |
filename |
String | Uploaded file name |
file_type |
String | stocks, us_stocks, mutual_funds |
records_count |
Integer | Number of holdings uploaded |
status |
String | success or failed |
Stores Ethereum wallet addresses for crypto tracking:
| Column | Type | Description |
|---|---|---|
id |
Integer | Primary key |
address |
String(42) | Ethereum address (0x...) |
label |
String | User-friendly name |
chains |
String | Comma-separated chains to scan |
is_active |
Boolean | Whether to include in scans |
created_at |
DateTime | When wallet was added |
last_scanned |
DateTime | Last scan timestamp |
This application supports three types of portfolio data uploads. For comprehensive format specifications, see DATA_FORMAT_SPECIFICATION.md.
Source: Indian broker holdings statements (Zerodha, Upstox, Groww, etc.)
Expected columns:
Stock Name,ISIN,Quantity,Average buy price,Buy value,Closing price,Closing value,Unrealised P&L
Requirements:
- Row 3 must contain date in format: "Holdings statement for stocks as on DD-MM-YYYY"
- All monetary values in INR
- Valid ISIN codes required
Source: DriveWealth Profit-Loss statement
Expected sheets:
- User Details: Contains period date range (YYYY-MM-DD to YYYY-MM-DD)
- Unrealized P&L - Summary: Holdings data with columns below
Expected columns:
Security,Quantity,Cost Basis (USD),Market Value (USD),Profit/Loss (USD),Profit/Loss (%)
Features:
- Automatic USD to INR conversion using Yahoo Finance real-time exchange rate
- 5-minute rate caching for performance
- Fallback rate: βΉ83.00/USD if API unavailable
Source: Broker mutual fund holdings statements
Expected columns:
Scheme Name,AMC,Category,Units,Invested Value,Current Value,Returns,XIRR
Requirements:
- All monetary values in INR
- NAV and XIRR values for performance tracking
Note: All parsers output a standardized format with 11 columns (type, name, symbol, isin, units, avg_price, invested_value, current_price, current_value, unrealized_pl, unrealized_pl_pct). All monetary values are stored in INR for consistency.
uv run pytestuv run ruff check src/If you encounter database errors, delete the database and re-upload:
rm data/portfolio.dbIf port 8501 is busy:
uv run streamlit run app/Home.py --server.port=8502Ensure you're in the project root and using uv:
cd investment-tracker-v2
uv syncIf USD to INR conversion fails:
- Check Internet Connection: Yahoo Finance API requires internet access
- Fallback Rate: Application automatically uses βΉ83.00/USD as fallback
- Manual Override: Edit
src/services/pricing.pyline 113 to set your preferred fallback rate
If data appears incorrect after upload:
- Check the Excel file format matches specifications in DATA_FORMAT_SPECIFICATION.md
- Delete the problematic snapshot using the "Delete Specific Snapshot" feature
- Re-upload with corrected file
- Gold/Precious metals tracking
- Fixed deposits & bonds support
- Google Sheets integration
- Automatic scheduled data refresh
- Tax harvesting suggestions (STCG/LTCG)
- Goal tracking & SIP recommendations
- Dividend tracking
- Historical exchange rate tracking
- Streamlit Cloud deployment
MIT License
Last Updated: January 2026