A command-line personal finance tracker that connects to your Zerodha account, maps your mutual funds to risk categories, allocates them across your financial goals, and tells you exactly how much SIP to set up, per risk bucket, per goal, to hit your targets on time.
Project description
Kite Goals — Personal Goal Based Mutual Fund Tracker
This is a simple CLI app to organise your Coin mutual funds into buckets as per your goals. Zerodha has long been requested for this feature but they don't seem to progress on this feature.
So, here's a command-line personal finance tracker that connects to your Zerodha account, maps your mutual funds to risk categories, allocates them across your financial goals, and tells you exactly how much SIP to set up — per risk bucket, per goal — to hit your targets on time.
What it does
- Fetches your live MF holdings from Zerodha via KiteConnect
- Groups funds into low / medium / high risk buckets using your own
mappings.json - Allocates your portfolio across goals in priority order (Emergency before Phone, etc.)
- Shows progress towards each goal with a visual bar
- Calculates the monthly SIP per risk bracket needed to close the gap by your deadline
- Suggests a rebalance plan that distributes a given monthly budget across your actual funds
Project structure
.
├── main.py # Orchestrator — runs the full flow
├── auth.py # Zerodha login and session management
├── portfolio.py # Groups holdings by risk category
├── goals.py # Waterfall allocation + SIP calculation
├── rebalance.py # Distributes monthly budget across funds
├── display.py # All terminal output / formatting
├── utils.py # load_json, validate_goals, months_between
│
├── funds.json # Auto-generated from Zerodha (or mock manually)
├── goals.json # Your goals — you define these
├── mappings.json # Which funds belong to which risk tier — you define these
└── .env # API credentials (never commit this)
Setup
1. Install dependencies
pip install kiteconnect python-dotenv
2. Create a .env file
zerodha_api_key=your_api_key_here
zerodha_api_secret=your_api_secret_here
Get these from Zerodha's developer console.
3. Define your risk mappings in mappings.json
Map each fund you hold to a risk tier. Fund names must match exactly what Zerodha returns in funds.json.
{
"high": ["HDFC SMALL CAP FUND - DIRECT PLAN"],
"medium": ["HDFC BALANCED ADVANTAGE FUND - DIRECT PLAN"],
"low": ["HDFC CORPORATE BOND FUND - DIRECT PLAN"]
}
4. Define your goals in goals.json
[
{
"name": "Emergency",
"priority": 0,
"target": 150000,
"deadline": "2026-12-01",
"allocation": {
"low": 0.7,
"medium": 0.2,
"high": 0.1
}
},
{
"name": "Phone",
"priority": 1,
"target": 15000,
"deadline": "2026-06-01",
"allocation": {
"low": 0.7,
"medium": 0.2,
"high": 0.1
}
}
]
⚠️ Each goal's allocation weights must sum to 1.0 — the app will raise an error if they don't.
Running it
python main.py
You'll be asked:
- Whether to fetch fresh holdings from Zerodha (opens a browser for login)
- Your monthly SIP budget for the rebalance plan (optional)
If you want to skip the Zerodha login and test locally, just create a funds.json manually with your holdings.
How allocation works
Goals are funded in priority order — your Emergency fund (priority 0) gets filled before the Phone goal (priority 1). This means your most critical goals are never starved by aspirational ones.
Within each goal, the allocation weights define how much of each risk bucket that goal claims. The pool of available money depletes as each goal is funded. Whatever remains after all goals is shown as unallocated surplus.
Portfolio (current value)
│
├── [Priority 0] Emergency
│ low → claims 70% of ₹150,000 from low bucket
│ medium → claims 20% of ₹150,000 from medium bucket
│ high → claims 10% of ₹150,000 from high bucket
│
└── [Priority 1] Phone
low → claims from whatever low has left
...
Sample output
════════════════════════════════════════════════════════════
GOAL ALLOCATIONS (priority order)
════════════════════════════════════════════════════════════
[0] EMERGENCY
Target : ₹150,000.00
Funded : ₹33,799.22
Gap : ₹116,200.78
Progress: [██████░░░░░░░░░░░░░░░░░░░░░░░░] 22.5%
Deadline: 2026-12-01 (10 months away)
SIP/mo breakdown to close gap by deadline:
low ₹ 10,396.61/month
high ₹ 1,223.47/month
Risk breakdown:
low needed ₹105,000.00 | funded ₹ 1,033.94 | gap ₹103,966.06
medium needed ₹ 30,000.00 | funded ₹ 30,000.00 | gap ₹ 0.00
high needed ₹ 15,000.00 | funded ₹ 2,765.27 | gap ₹ 12,234.73
Adding a new fund
- Buy the fund on Zerodha
- Add it to
mappings.jsonunder the appropriate risk tier - Run
main.pyand fetch fresh holdings — it will appear automatically
Roadmap ideas
- Historical SIP tracking (did you actually invest what was planned last month?)
- Auto-calculate allocation weights from a target risk profile
- Export summary to PDF or spreadsheet
- Multi-currency support
- Web UI / dashboard
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file buckets_for_zerodha-0.1.0.tar.gz.
File metadata
- Download URL: buckets_for_zerodha-0.1.0.tar.gz
- Upload date:
- Size: 7.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6dcaf50f09ed58b35c3d2521b927fc6a93c00e321fedb776f8210bbee3eb0c57
|
|
| MD5 |
259d22994cf5d3a72e315df3c17e5422
|
|
| BLAKE2b-256 |
b07022547d8ae7bb24ca35ff722d1c7deda21a64d3772233b5f505c6bb8ca674
|
File details
Details for the file buckets_for_zerodha-0.1.0-py3-none-any.whl.
File metadata
- Download URL: buckets_for_zerodha-0.1.0-py3-none-any.whl
- Upload date:
- Size: 10.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2a1f8af22ab9d8633026f17e0f40b0e96a6e2c25098ce7b7df03bc3feb04edf9
|
|
| MD5 |
9677142b635a9c7ad3df9ea39fed204b
|
|
| BLAKE2b-256 |
cf172e0d01ddce14feba388cfafb1ba0f942809fe37642f0869e5bb32e6408f3
|