Lakshmi
(Screenshot of the
lak command in action)
Lakshmi is an open-source Python library and command-line tool (lak) for
managing an index-investing portfolio, inspired by the
Bogleheads
philosophy. It is built for US investors and reports values in dollars.
Why Lakshmi?
Most modern portfolio trackers require sharing sensitive credentials with third-party servers, struggle with tax-location strategies, or push active trading features. Lakshmi takes a different approach:
- 🔒 Privacy & Local-First: Your portfolio lives in a plain-text YAML file on your machine. There are no accounts to link and no credentials to share. The only network access is looking up public prices for the tickers you hold.
- 🎯 Asset Allocation & Location: Track your target allocation across Taxable, Tax-Deferred (401(k), Traditional IRA) and Tax-Exempt (Roth IRA) accounts, and see how each asset class is spread across account types.
- ⚖️ Actionable Rebalancing & What-Ifs: Doesn't just show values. Try hypothetical trades, and get suggestions for where to put new contributions (or take withdrawals from) to move back toward your target allocation.
- 💡 Tax Awareness: Tax-lot tracking, tax-loss harvesting candidates, and native support for Treasury I/EE Bonds and Vanguard funds without tickers.
- 📈 Performance Tracking: Dollar-weighted returns (IRR) computed from periodic portfolio checkpoints, with contributions and withdrawals recorded as cash flows.
Installation
Lakshmi requires Python 3.9 or newer and is available on
PyPI. To use the lak command, install it
with pipx (or
uv), which keeps it in its own environment:
pipx install lakshmi
# Or, with uv
uv tool install lakshmi
To use Lakshmi as a library, pip install lakshmi inside your project's
environment.
On Arch Linux, you can also install it from the AUR via an AUR helper or manually:
yay -S python-lakshmi
Quick start
The fastest way to see what Lakshmi does is to try it on the example portfolio:
curl -o ~/portfolio.yaml https://sarvjeets.github.io/lakshmi/docs/portfolio.yaml
lak list assets total aa al
The first run is slow because it fetches names and prices. After that they are cached (prices for a day), so later runs are fast.
To build your own portfolio, either edit a copy of the example file, or use
lak to create one step by step:
- Enter your desired asset allocation:
lak init. This opens an editor with an example allocation. If you want to keep the example as is, make any small edit (e.g. delete a comment) before saving, sincelaktreats an unchanged file as an aborted edit. - Add your accounts (401(k), Roth IRA, Taxable, etc.) with
lak add account. Run it once per account. - Add assets to an account with
lak add asset -p TickerAsset -t <account>, where<account>is a substring that uniquely matches an account name. Other asset types (ManualAsset,VanguardFund,IBonds,EEBonds) are listed inlak add asset --help. - View everything with
lak list assets total aa al.
For a detailed walkthrough, see creating a portfolio in the lak user guide. For tips and tricks (moving config files, shell completion, multiple portfolios, automatic emails), see Lakshmi Recipes.
Features
Plan
- Specify a nested target asset allocation and track it across all accounts.
- List assets, asset allocation and asset location.
- Run what-if scenarios to see how a change would affect your allocation before you make it.
Decide
- Suggest which funds to put new money into (or withdraw from) to keep the actual allocation close to the target. (Beta)
- Suggest how to rebalance the funds in a given account.
- Check whether any asset class has drifted outside its rebalancing bands.
- Find tax lots that are candidates for tax-loss harvesting.
Track
- Add, edit and delete accounts and assets. Market values update automatically.
- Supported assets: manual assets, anything with a ticker, Vanguard funds without tickers, EE Bonds and I Bonds.
- Track tax lots for assets.
- Track portfolio performance (IRR) and cash flows over time.
Scope and limitations
- US only. Taxes, account types and I/EE Bonds follow US rules, and values are in dollars.
- Prices come from Yahoo Finance (via
yfinance) and Treasury/Vanguard data. If a source is down or rate limits you,lakcan't refresh that asset. - Tax-loss harvesting is a starting point, not tax advice. It assumes specific-lot identification and does not yet check for wash sales, including purchases in your other accounts.
lak analyze allocateis a beta feature. Sanity check its suggestions before acting on them.
Command-line cheat sheet
Run lak --help (or add --help to any command) for current options. The
lak user guide documents
every command in detail.
| To do this | Run |
|---|---|
| See assets, totals, allocation and location | lak list assets total aa al |
| See tax lots and gains | lak list lots |
| Try a hypothetical trade | lak whatif asset -a VTI -50 asset -a VXUS -t Taxable 50 |
| Decide where new money goes | lak whatif account -t Taxable 100 then lak analyze allocate -t Taxable |
| Check if rebalancing is needed | lak analyze rebalance |
| Look for tax-loss harvesting candidates | lak analyze tlh |
| Save a checkpoint for performance tracking | lak add checkpoint |
| See performance (IRR) | lak list performance |
Library
The lakshmi library can also be used directly. The modules and classes are
well documented, and the
tests contain
numerous examples for each method and class.
Example: build the example portfolio and print its allocation
This code constructs the example portfolio and prints its asset allocation, asset location and assets:
from lakshmi import Account, AssetClass, Portfolio
from lakshmi.assets import TaxLot, TickerAsset
from lakshmi.table import Table
def main():
asset_class = (
AssetClass('All')
.add_subclass(0.6, AssetClass('Equity')
.add_subclass(0.6, AssetClass('US'))
.add_subclass(0.4, AssetClass('Intl')))
.add_subclass(0.4, AssetClass('Bonds')))
portfolio = Portfolio(asset_class)
(portfolio
.add_account(Account('Schwab Taxable', 'Taxable')
.add_asset(TickerAsset('VTI', 1, {'US': 1.0})
.set_lots([TaxLot('2021/07/31', 1, 226)]))
.add_asset(TickerAsset('VXUS', 1, {'Intl': 1.0})
.set_lots([TaxLot('2021/07/31', 1, 64.94)])))
.add_account(Account('Roth IRA', 'Tax-Exempt')
.add_asset(TickerAsset('VXUS', 1, {'Intl': 1.0})))
.add_account(Account('Vanguard 401(k)', 'Tax-Deferred')
.add_asset(TickerAsset('VBMFX', 20, {'Bonds': 1.0}))))
# Save the portfolio
# portfolio.save('portfolio.yaml')
print('\n' + portfolio.asset_allocation_compact().string() + '\n')
print(Table(2, coltypes=['str', 'dollars'])
.add_row(['Total Assets', portfolio.total_value()]).string())
print('\n' + portfolio.asset_allocation(['US', 'Intl', 'Bonds']).string())
print('\n' + portfolio.assets().string() + '\n')
print(portfolio.asset_location().string())
if __name__ == "__main__":
main()
Contributing
Contributions are welcome. All development happens on the develop branch.
See CONTRIBUTING.md
for how to set up a development environment, run the tests and submit changes.
Background
This project is inspired by the Bogleheads forum. Bogleheads focus on a simple but powerful philosophy that allows investors to achieve above-average returns after costs. This tool is built around the same principles to help an average investor manage their investing portfolio. The Bogleheads wiki is a great introduction to basic investing concepts like asset allocation and asset location.
Lakshmi (meaning "She who leads to one's goal") is one of the principal goddesses in Hinduism. She is the goddess of wealth, fortune, power, health, love, beauty, joy and prosperity.
License
Distributed under the MIT License. See LICENSE for more information.
Acknowledgements
I am indebted to the following folks whose wisdom has helped me tremendously in my investing journey: John Bogle, Taylor Larimore, Nisiprius, Livesoft, Mel Lindauer and LadyGeek.
This project would not have been possible without my wife Niharika, who helped me come up with the initial idea and encouraged me to start working on this project.
The not-so-fine print
The author is not a financial adviser and you agree to treat this tool for informational purposes only. The author does not promise or guarantee that the information provided by this tool is correct, current, or complete, and it may contain technical inaccuracies or errors. The author is not liable for any losses that you might incur by acting on the information provided by this tool. Accordingly, you should confirm the accuracy and completeness of all content, and seek professional advice taking into account your own personal situation, before making any decision based on information from this tool.
In a nutshell:
- The information provided by this tool is not financial advice.
- The author is not an expert or financial adviser.
- Consult a financial and/or tax adviser before taking action.
Metadata
Release files for lakshmi 3.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| lakshmi-3.1.0.tar.gz | 70.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| lakshmi-3.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 125.0 kB
Release files / lakshmi-3.1.0.tar.gz
| Download URL | lakshmi-3.1.0.tar.gz |
|---|---|
| Size | 70.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3fb2ffae59f81c62db971e5309cd96a4b3af244155cf0de7087b84eb00bbb00c
|
|
BLAKE2b-256 checksum How to use checksums |
65de0a143d6459b8fea357d4431185568ba0350ddde07019cb161b394e04cc30
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.7
|
Release files / lakshmi-3.1.0-py3-none-any.whl
| Download URL | lakshmi-3.1.0-py3-none-any.whl |
|---|---|
| Size | 54.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4b9e42721bd285fe2ff9e4de63ecd4b6576c3cdded8c8b808b73b61c20ad33c5
|
|
BLAKE2b-256 checksum How to use checksums |
7b0a76c4f7e89265c724da6233aac9ed7a36df774bf309ff55a1cad32f4935a7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.7
|