- Introduction
- Configuration files and directories
- Portfolio file syntax
- Creating a Portfolio
- Help and usage
lak provides a command-line interface to the lakshmi library. lak is meant as a tool for managing your investing portfolio. It is inspired by the Bogleheads philosophy.
Bogleheads wiki is a great resource for introduction to basic investing concepts like asset allocation, asset location, etc. The rest of this guide assumes some familiarity with these investing concepts.
This tool is built for US investors and prints portfolio values in dollars.
lak
stores all the information about accounts, assets, etc. in a portfolio
file. By default, this portfolio is saved in ~/porfolio.yaml
. The
portfolio file syntax section explains the syntax
of this file. Backing up this file periodically is strongly recommended.
The performance related data (checkpoints of the portfolio values, etc.) is
stored in a performance file. By default, this data is stored in
~/.perfomance.yaml
. lak list performance
and lak info performance
commands use this file to compute historical performance stats.
This file is created the first time lak add checkpoint
is called. Entries
in this file can be added/modified or deleted via the lak edit checkpoint
and
lak delete checkpoint
commands.
It is recommended to save portfolio checkpoints periodically (every month or quarter, or everytime money is added or removed from the portfolio) so that the performance of the portfolio can be tracked. The tool interpolates the value of the portfolio between saved checkpoints whenever needed.
In addition, lak
caches the information about the assets in a cache
directory to ensure that subsequent calls to lak
are fast. By default,
the cache directory is ~/.lakshmicache. Storing any other file in this
directory is strongly discouraged.
lak
caches fund/stock/ETF names for a year, stock prices for a day and
the current value of I Bonds and EE Bonds for a month (it refreshes the values
on the 1st of every month).
lak
cleans up old cached files in this directory when starting up,
and usually it doesn't need any sort of periodic clean-up. The directory and
the files inside it can be safely deleted. The next call to lak
will
re-create the directory/files, but as expected it would be really slow.
Caching can be permanently disabled using the .lakrc
file (not recommended)
or you can force lak
to temporarily refresh cached values by specifying -r
or --refresh
flag to lak
command:
# Reload cached information such as prices etc.
$ lak -r ...
$ lak --refresh ...
Both the portfolio file and the cache directory locations can be overridden
by an optional ~/.lakrc
file. Like everything else in Lakshmi, this is
a text file in YAML format. An example .lakrc
file looks like:
# Example ~/.lakrc file
# Comments begin with '#' and are ignored.
portfolio: '~/.config/lak/portfolio.yaml'
performance: ~/.config/lak/.performance.yaml
cache: '~/.cache/lakshmicache'
Setting the cache to an empty value disables caching (not recommended):
# ~/.lakrc file that disables caching (not recommended).
cache:
By default lak
assumes that the config file is located at ~/.lakrc
, but
this location can be overriden by a flag or an environment variable. For
example:
# Use lakrc from a different location
$ lak -c ~/.config/lak/.lakrc ...
# The same using environment variable.
$ LAK_CONFIG=~/.config/lak/.lakrc lak ...
The config file can also be specified via the LAK_CONFIG
environment
variable, which can be used instead of repeatedly specifying the config file
via the option. For example, add this to your shell's initialization config
(.bashrc
or .zshrc
) to always use an alternate location for your lakrc
:
export LAK_CONFIG=~/.config/lak/.lakrc
lak
provides add and edit commands to modify
different parts of the portfolio, and these commands present the
user with examples while editing the portfolio. As such, it is better
to rely on those commands instead of directly editing the portfolio file.
The portfolio file is a text file in YAML syntax and consists of only dictionaries and lists.
As a convention, in the format below, {} represents a dictionary and [] represents a repeated list. Entries that are optional are surrounded by <>. For example, the lakrc file format can be described as:
lakrc := { < 'portfolio': portfolio_filename >,
< 'cache': cache_directory > }
portfolio_filename := String
cache_directory := < String >
portfolio.yaml shows an example portfolio file.
The portfolio file syntax is:
portfolio := { 'Asset Classes' : asset_class,
'Accounts' : [ account ] }
asset_class := { 'Name' : String,
'Children' : [ asset_class_children ] }
# The 'Ratio' for all children of an asset_class should add up to 1.0
asset_class_children := { 'Ratio' : Float,
'Name' : asset_class_name,
'Children' : [ asset_class_children ] }
asset_class_name := String
account := { 'Name' : String,
'Account Type': String,
'Assets': [ asset ] }
asset := { 'ManualAsset' : manual_asset |
'TickerAsset' : ticker_asset |
'VanguardFund' : vanguard_fund_asset |
'IBonds' : ibond_asset |
'EEBonds' : eebonds_asset }
manual_asset := { 'Name' : String,
'Value' : dollars,
'Asset Mapping' : asset_mapping }
dollars := Float
# The floats (ratios) should add up to 1.0
asset_mapping := { asset_class_name : Float,
asset_class_name : Float,
... }
ticker_asset := { 'Ticker' : String,
'Shares' : Float,
'Asset Mapping' : asset_mapping,
< 'Tax Lots' : tax_lots > }
tax_lots := [ { 'Date' : date,
'Quantity' : Float,
'Unit Cost' : dollars } ]
# Date is specified in YYYY/MM/DD format.
date := String
vanguard_fund_asset := { 'Fund Id' : Integer,
'Shares' : Float,
'Asset Mapping' : asset_mapping,
< 'Tax Lots' : tax_lots > }
ibond_asset := { 'Asset Mapping' : asset_mapping,
'Bonds' : [ treasury_bond ] }
treasury_bond := { 'Issue Date' : short_date,
'Denomination' : dollars }
eebonds_asset := { 'Asset Mapping' : asset_mapping,
'Bonds' : [ treasury_bond ] }
- Asset Classes are tracked and
presented in the asset allocation view by the
lak list aa
command. These asset class names are also referred by individual assets to specify their distribution across these asset classes. Each asset class can be further sub-divided into asset classes (children) and their respective percentages. The percentages of children of a particular asset class should add up to 100%. Example Asset Class section. - Account represents a collection of assets. The account name could be
anything ('Schwab', 'Vanguard Taxable', 'Her Roth IRA', etc.) but it needs
to be unique across the portfolio. The type of the account is used when
printing the asset location by the
lak list al
command. Example Account section. - Asset represents a particular fund, ETF, a collection of treasury bonds,
etc. Some assets are pre-defined in
lak
and more types of assets can be added by modifying thelakshmi.assets
module. Each asset needs to specify how it maps to the asset classes defined earlier. An asset can map to multiple asset classes, and the sum of percentages across the asset classes should add up to 100%.- Manual Asset is the simplest asset. As the name suggests, this asset is tracked manually. The value of this asset needs to be specified and is not automatically updated. Example Manual Asset section.
- Ticker Asset is any asset that has a ticker symbol (e.g. 'VTI',
'GOOG', etc.). The value of these assets are automatically pulled from the
internet and kept up-to date. Tax lots can also be specified and tracked
for these assets. This is useful for taxable accounts and
lak analyze tlh
can notify when/if these tax lots can be tax loss harvested. Example Ticker Asset section - Vanguard Fund are funds that don't have a ticker symbol associated with them. Most Vanguard funds do have ticker symbols associated with them and as such should be tracked by specifying them as TickerAsset. An example of such funds are the Institutional funds (e.g. 'Vanguard Institutional Total Bond Market Index Trust' which has a numeric id, 7555, but not a ticker symbol). These funds can also contain tax lot information. Example Vanguard Fund section
- I Bonds and EE Bonds are bought and sold electronically at Treasury Direct or can be purchased in paper format via tax refund. This asset tracks value of multiple I Bonds or EE Bonds by pulling the current value from the Treasury Direct website. If you have a lot of bonds, this could be very slow. Example I Bonds section. Example EE Bonds section.
Most of the commands in lak
require that a portfolio file already
exists (except lak init
which creates a new portfolio file). There
are two simple ways of importing your portfolio into lak
:
- Use a text editor to create the portfolio file. This might be faster, but also requires a good understanding of the portfolio file syntax. As such, this is not recommended for most users.
- Use the
lak init
andlak add
commands to create the portfolio. Under the hood, these commands edit parts of the portfolio file, but provide help and examples relevant to the particular section of the portfolio being edited.
To make things easier, it is recommended to copy an existing file to ~/portfolio.yaml or the location specified in the .lakrc file. The open up your favorite editor and modify this file using the format specified in portfolio file syntax section.
This section will run through the process of creating a portfolio file. Please go through the documentation of lak init and lak add commands for more information on these commands.
The example commands in this section will re-create this file. While following these examples, please change the details to match your own portfolio instead of the example one.
For more information on how to come up your desired asset allocation, please refer to Bogleheads wiki.
For our example, we want to create the following portfolio:
All -> Equity 60% and Bonds 40%
Equity -> US 60% and Intl 40%
Use the lak init
command:
$ lak init
It will open up your default text-editor with:
# The asset classes across which to track asset allocation
# (e.g. with lak list aa) command.
# The following shows an example of a nested asset allocation:
# All -> Equity 60% and Bonds 40%
# Equity -> US 60% and Intl 40%
#
# Name of the asset class.
Name: All
# Optionally the children of this asset class (each of which
# is itself an asset class and can have more asset classes
# as children).
Children:
- Ratio: 0.6
Name: Equity
Children:
- Ratio: 0.6
Name: US
- Ratio: 0.4
Name: Intl
- Ratio: 0.4
Name: Bonds
As it turns out the initial example matches our desired asset allocation,
so there is no need to change it. But, with no changes, lak init
assumes
the user aborted the edits. Make any minor edit (delete a comment) to accept
this initial file as your portfolio.
After saving, this creates a new portfolio file.
There are three accounts in the example portfolio file. Let's add them one by one.
$ lak add account
This opens up an editor with:
# An Account represents a collection of Assets (e.g. ETFs or Funds)
# Name of the account, must be unique among all accounts in the portfolio.
Name: Unique-name-for-account
# Type of the account, e.g. Taxable, Tax-Exempt, Tax-Deferred, etc. This
# name is used to group accounts when listing the Asset Location with
# the 'lak list al' command.
Account Type: Tax-Exempt
Modify the file to change the account name and type:
Name: Schwab Taxable
Account Type: Taxable
Re-run the lak add account
command to add more accounts as needed. In our
case this would mean we will the following accounts:
$ lak add account
# Paste the following lines in the editor.
Name: Roth IRA
Account Type: Tax-Exempt
# Save the file and exit.
$ lak add account
# Paste the following lines in the editor.
Name: Vanguard 401(k)
Account Type: Tax-Deferred
# Save the file and exit.
Now we are done adding accounts. Let's add some assets to these accounts.
There are a number of kinds of assets that are supported in lakshmi. Please refer to portfolio file syntax section for a brief description of each of the asset. In our example, we are just one asset type: TickerAsset.
To add VTI to "Schwab Taxable" account:
$ lak add asset -p TickerAsset -t Schwab
Note that we just entered "Schwab" instead of the full name as
lak
commands do a sub-string matching (as long as it can pull up a
unique account or asset with that sub-string).
The command above opens up an editor:
# A TickerAsset represents an asset with a ticker symbol. The value of
# these assets can be pulled and updated from the internet (Yahoo Finance).
# The ticker symbol, e.g. 'VTI' or 'VXUS'
Ticker: ITOT
# The number of shares owned.
Shares: 123
# How this asset maps to the asset classes defined in the portfolio.
# This is used to generate asset allocation (e.g. when using
# `lak list aa` command)
Asset Mapping:
US: 1.0
# Optionally the tax lot information for the asset.
Tax Lots:
- Date: 2020/03/23
Quantity: 123
Unit Cost: 50.39
Modify the above file to add details for VTI instead:
Ticker: VTI
Shares: 1
Asset Mapping:
US: 1.0
Tax Lots:
- Date: 2021/07/31
Quantity: 1
Unit Cost: 226
Save and exit the text-editor. It will save the asset in portfolio. Add other assets to Taxable, Roth and 401(k) accounts:
$ lak add asset -p TickerAsset -t Taxable
# Paste the following lines in the editor.
Ticker: VXUS
Shares: 1
Asset Mapping:
Intl: 1.0
Tax Lots:
- Date: 2021/07/31
Quantity: 1
Unit Cost: 64.94
# Save the file and exit.
$ lak add asset -p TickerAsset -t Roth
# Paste the following lines in the editor.
Ticker: VXUS
Shares: 1
Asset Mapping:
Intl: 1.0
# Save the file and exit.
$ lak add asset -p TickerAsset -t 401
# Paste the following lines in the editor.
Ticker: VBMFX
Shares: 20
Asset Mapping:
Bonds: 1.0
# Save the file and exit.
Verify the portfolio file was properly created:
$ lak list assets
Account Asset Value
--------------- -------------------------------------------------------- -------
Schwab Taxable Vanguard Total Stock Market Index Fund ETF Shares $228.87
Schwab Taxable Vanguard Total International Stock Index Fund ETF Shares $65.46
Roth IRA Vanguard Total International Stock Index Fund ETF Shares $65.46
Vanguard 401(k) Vanguard Total Bond Market Index Fund Investor Shares $227.60
The steps above should create an output similar to this (except the Value column which depends on the market value of the ETFs added).
For up to date help, please use the --help
flag after a command
or sub-command. For example:
# Help for lak
$ lak --help
# Help for lak list
$ lak list --help
# Help for lak add asset
$ lak add asset --help
lak
is the top-level command:
$ lak --help
Usage: lak [OPTIONS] COMMAND [ARGS]...
lak is a simple command line tool inspired by Bogleheads philosophy.
Detailed user guide is available at:
https://sarvjeets.github.io/lakshmi/docs/lak.html
Options:
--version Show the version and exit.
-r, --refresh Re-fetch all data instead of using previously cached
data. For large portfolios, this would be extremely slow.
-c, --config PATH The configuration file. [env var: LAK_CONFIG; default:
~/.lakrc]
--debug If set, prints stack track when an exception is raised.
--help Show this message and exit.
Commands:
add Add new entities to the portfolio.
analyze Analyze the portfolio.
delete Delete different entities from the portfolio.
edit Edit parts of the portfolio.
info Print detailed information about parts of the portfolio.
init Initializes a new portfolio by adding asset classes.
list Command to list various parts of the portfolio.
whatif Run hypothetical what if scenarios by modifying the total...
The option --refresh
will force lak
commands to not used cached
values (See cache for details) and fetch new data from internet.
If your portfolio is large, this will be really slow.
A potential use case would be for fetching the current value of a TickerAsset (the prices are cached for a day). In line with boglehead philosophy, it is strongly recommended to not check your portfolio multiple times a day. The decision to cache price information for a day was partly motivated to reduce the urge to check your portfolio multiple times a day to see "how it is doing".
This command is used to create an initial portfolio. Please see Using lak command to create portfolio section for details.
$ lak init --help
Usage: lak init [OPTIONS]
Initializes a new portfolio by adding asset classes. This command can be
used to create an empty portfolio file if one doesn't exist.
Options:
--help Show this message and exit.
If you attempt to use lak init
when a portfolio file exists, it cowardly
refuses to over-write an existing portfolio:
$ lak init
Error: Portfolio file already exists: /home/username/portfolio.yaml
To resolve this error, please delete the existing portfolio file.
This command is used to add accounts, assets or checkpoints:
$ lak add --help
Usage: lak add [OPTIONS] COMMAND [ARGS]...
Add new entities to the portfolio.
Options:
--help Show this message and exit.
Commands:
account Add a new account to the portfolio.
asset Add a new asset to the portfolio.
checkpoint Checkpoint the current portfolio value.
Using lak command to create portfolio provides some examples for this command.
$ lak add account --help
Usage: lak add account [OPTIONS]
Add a new account to the portfolio.
Options:
--help Show this message and exit.
$ lak add asset --help
Usage: lak add asset [OPTIONS]
Edit assets in the portfolio.
Options:
-p, --asset-type [ManualAsset|TickerAsset|VanguardFund|IBonds|EEBonds]
Add this type of asset. [required]
-t, --account substr Add asset to this account (a sub-string that
matches the account name). [required]
--help Show this message and exit.
The account names used should be unique across the portfolio. The assets (or asset names) used inside an Account should be unique, but you can have the same asset name across accounts.
For information on different asset types, please refer to the list provided in the Portfolio file syntax section.
$ lak add checkpoint --help
Usage: lak add checkpoint [OPTIONS]
Checkpoint the current portfolio value. This creates a new checkpoint for
today with the current portofolio value (and no cash-flows). To add
cashflows to this checkpoint, please use the --edit flag.
Options:
-e, --edit If set, edit the checkpoint before saving it.
--help Show this message and exit.
This command checkpoint the current value of the portfolio. This checkpoint
data is saved in the performance file, which is used to
compute historical portfolio performance. If a performance file does not
exist, this command will create a new file. The --edit
flag can be used to
edit the checkpoint before saving it. This is helpful if you want to add any
cashflows. For example,
$ lak add checkpoint --edit
This will open your default text-editor with:
Portfolio Value: 500.89
Inflow: 0
Outflow: 0
# # Lines starting with "#" are ignored and an empty message aborts this command.
# # The total value of the portfolio (after all the inflows and outflows).
# Portfolio Value: 10_000.00
# # The amount of money added to the portfolio (optional).
# Inflow: 100.00
# # The amount of money withdrawn from the portfolio (optional).
# Outflow: 0
#
If any money was added (inflow) or removed (outflow) from the portfolio, those amounts can be added before the checkpoint is saved. The inflows/outflows are used to compute the Internal rate of return (IRR) of the portfolio.
The saved checkpoints can listed via lak list checkpoints
command.
lak delete chekpoint
and lak edit checkpoint
can be used to delete or
edit an already saved checkpoint.
lak list
command is used to check on your portfolio's assets, asset
allocation, etc.:
$ lak list --help
Usage: lak list [OPTIONS] COMMAND1 [ARGS]... [COMMAND2 [ARGS]...]...
Command to list various parts of the portfolio.
Options:
-f, --format [plain|simple|github|grid|fancy_grid|pipe|orgtbl|rst|mediawiki|html|latex|latex_raw|latex_booktabs|latex_longtable|tsv]
Set output table format. For more
information on table formats, please see
"Table format" section on:
https://pypi.org/project/tabulate/
--help Show this message and exit.
Commands:
aa Prints the Asset Allocation of the portfolio.
al Prints the Asset Location of the portfolio.
assets Prints all assets in the portfolio and their current values.
checkpoints Prints the portfolio's saved checkpoints.
lots Prints tax lot information for all the assets.
performance Prints summary stats about portfolio's performance.
total Prints the total value of the portfolio.
whatifs Prints hypothetical what ifs for assets and accounts.
lak list
command requires a sub-command: assets
, total
, aa
,
al
or whatifs
, which are explained in the following sections.
The lak list
commands can be chained. For example, to print all assets
and the total value of the portfolio:
$ lak list assets total
The --format
option is useful for changing the format of the output.
The lakshmi
library uses tabulate
internally to display tables. A description of all the available format
options can be found in the
Table format section.
For example, to list assets in a fancy GitHub table format:
$ lak list -f github assets
Account | Asset | Value |
---|---|---|
Schwab Taxable | Vanguard Total Stock Market Index Fund ETF Shares | $230.00 |
Schwab Taxable | Vanguard Total International Stock Index Fund ETF Shares | $65.93 |
Roth IRA | Vanguard Total International Stock Index Fund ETF Shares | $65.93 |
Vanguard 401(k) | Vanguard Total Bond Market Index Fund Investor Shares | $226.80 |
This command prints all the assets in the portfolio in a table format.
$ lak list assets --help
Usage: lak list assets [OPTIONS]
Prints all assets in the portfolio and their current values.
Options:
-s, --short-name Print the short name of the assets as well (e.g. Ticker
for assets that have it).
-q, --quantity Print the quantity of the asset (e.g. quantity/shares
for assets that have it).
--help Show this message and exit.
For the portfolio file created previously:
$ lak list assets
Account Asset Value
--------------- -------------------------------------------------------- -------
Schwab Taxable Vanguard Total Stock Market Index Fund ETF Shares $228.87
Schwab Taxable Vanguard Total International Stock Index Fund ETF Shares $65.46
Roth IRA Vanguard Total International Stock Index Fund ETF Shares $65.46
Vanguard 401(k) Vanguard Total Bond Market Index Fund Investor Shares $227.60
The Account and Asset columns are self-explanatory. The asset name for
some assets (e.g. TickerAsset
and VanguardFund
) is fetched from the
internet and cached for a year. The current value of the asset
is fetched from the internet (except for ManualAsset
) and cached for a
day.
The short name and quality of the asset can also be printed:
$ lak list assets -s -q
Account Name Quantity Asset Value
--------------- ------ ---------- -------------------------------------------------------- -------
Schwab Taxable VTI 1 Vanguard Total Stock Market Index Fund ETF Shares $228.93
Schwab Taxable VXUS 1 Vanguard Total International Stock Index Fund ETF Shares $65.59
Roth IRA VXUS 1 Vanguard Total International Stock Index Fund ETF Shares $65.59
Vanguard 401(k) VBMFX 20 Vanguard Total Bond Market Index Fund Investor Shares $226.80
This command can be used to print the sum total of value grouped by account or account types:
$ lak list accounts --help
Usage: lak list accounts [OPTIONS]
Prints all the accounts in the portfolio and their current values.
Options:
-g, --group If set, aggregate the account values by account types.
--help Show this message and exit.
For the portfolio created previously:
$ lak list accounts
Account Account Type Value Percentage
--------------- -------------- ------- ------------
Schwab Taxable Taxable $280.91 50%
Roth IRA Tax-Exempt $61.54 11%
Vanguard 401(k) Tax-Deferred $215.00 39%
The last columns shows the percentage of value of assets in that account.
The account values can also be aggregated by account types:
$ lak list accounts -g
Account Type Value Percentage
-------------- ------- ------------
Taxable $280.91 50%
Tax-Exempt $61.54 11%
Tax-Deferred $215.00 39%
lak list lots
prints the tax-lots (if specified) for all the assets in the
portfolio. Tax-lots can be specified when adding a new asset
(lak add asset
), or when editing (lak edit asset
) a given asset.
To print tax-lots for a single asset, please use lak info asset
command
instead.
For the portfolio file created previously:
$ lak list lots
Short Name Date Cost Gain Gain%
------------ ---------- ------- ------ -------
VTI 2021/07/31 $226.00 +$8.29 4%
VXUS 2021/07/31 $64.94 +$2.06 3%
lak list total
prints the total value of the portfolio:
$ lak list total --help
Usage: lak list total [OPTIONS]
Prints the total value of the portfolio.
Options:
--help Show this message and exit.
For the portfolio file created previously:
$ lak list total
------------ -------
Total Assets $587.39
------------ -------
lak list aa
prints the
asset allocation.
There are a few different formats available:
$ lak list aa --help
Usage: lak list aa [OPTIONS]
Prints the Asset Allocation of the portfolio. For more information, please
see https://www.bogleheads.org/wiki/Asset_allocation
Options:
--compact / --no-compact Print the Asset allocation tree in a vertically
compact format [default: compact]
-c, --asset-class TEXT If provided, only print asset allocation for these
asset classes. This is a comma separated list of
asset classes (not necessarily leaf asset classes)
and the allocation across these asset classes
should sum to 100%.
--help Show this message and exit.
There are three ways to print asset allocation. Let's look at all three in detail.
- lak list aa --compact
The default option is to print the asset allocation in compact format. This view packs the most amount of information in the output:
$ lak list aa
Class A% D% Class A% D% Actual% Desired% Value Difference
------- ---- ---- ------- ---- ---- --------- ---------- ------- ------------
Equity 61% 60% US 64% 60% 39% 36% $230.00 -$18.08
Intl 36% 40% 22% 24% $131.86 +$9.42
Bonds 39% 40% 39% 40% $226.80 +$8.66
Let's look at each column in detail:
- Class: This column shows the asset classes arranged as a horizontal tree. For example, in the output above, there are two asset classes in the top-level: Equity and Bonds. Equity is further sub-divided into US and Intl.
- A% and D%: A% and D% stands for Actual percentage and desired percentage, respectively. These columns refer to the Class column immediately left of them, and shows the relative percentage of those assets in the parent asset class. For example, the columns A% right next to US and Intl signifies that the actual allocation (based on current balance) of these asset classes is 64% and 36% respectively. The D% column tells us based on the desired asset allocation specified for the portfolio, the desired relative percentages of these assets should be 60% and 40%.
- Actual% and Desired%: Finally, the last columns show the absolute percentages for the leaf asset classes (US, Intl and Bonds in the above table). These leaf asset classes are the asset classes immediately to the left of the values printed in Actual% and Desired% column. Note that the A%/D% values and the Actual%/Desired% values for US and Intl are different. This is expected as A% and D% refers to the percentages of these assets in Equity; however, the Actual% and Desired% refers to the percentages of these asset classes in the overall portfolio.
- Value and Difference: Finally, the Value column shows the amount of money allocated to the leaf asset class. The Difference column shows how far the money allocated is to the desired amount of money allocated. For example, the table above shows that if we sold $18.08 of US and bought $9.42 and $8.66 of Intl and Bonds, we will match the actual allocation to the desired allocation perfectly.
The Difference column is an important column to look at, especially when
making or planning (see the section on lak whatif
) changes
to the asset allocation. When adding new money, asset classes with the largest
value of Difference should be prioritized and when withdrawing money, the
asset classes with the lowest value of Difference should be prioritized.
Rebalancing can be achieved by just following the current values in this
column (also see lak analyze rebalance
section).
- lak list aa --no-compact
This option still prints asset allocation in a tree format but prints less information than the default option:
$ lak list aa --no-compact
Class Actual% Desired% Value
------- --------- ---------- -------
All:
Equity 61% 60% $361.86
Bonds 39% 40% $226.80
Equity:
US 64% 60% $230.00
Intl 36% 40% $131.86
The Actual% and Desired% columns correspond to the relative
allocation of the asset class respective to the parent asset class.
These columns correspond to A% and D% columns in lak list aa
output.
- lak list aa --asset-class
This command print's asset allocation, but only across the asset classes
explicitly mentioned in the --asset-class
flag. For example:
$ lak list aa --asset-class US,Intl,Bonds
Class Actual% Desired% Value Difference
------- --------- ---------- ------- ------------
US 39% 36% $230.00 -$18.08
Intl 22% 24% $131.86 +$9.42
Bonds 39% 40% $226.80 +$8.66
# Space in the asset class list requires quotes around them.
$ lak list aa --asset-class 'Equity, Bonds'
Class Actual% Desired% Value Difference
------- --------- ---------- ------- ------------
Equity 61% 60% $361.86 -$8.66
Bonds 39% 40% $226.80 +$8.66
The column meaning is similar to the default output of lak list aa
command
(explained above).
It is important to ensure that the asset classes specified completely
cover the allocation in the portfolio, without any overlap. Here are
some examples that will throw an error (AssetAllocation called with overlapping Asset Classes or Asset Classes which does not cover the full tree.
):
lak list aa --asset-class Equity,US
: Overlapping asset classes.lak list aa --asset-class US, Intl
: The list doesn't cover Bonds.
This command prints the asset location across the types of accounts. The information is important to ensure that assets are placed efficiently across accounts.
$ lak list al
Asset Class Account Type Percentage Value
------------- -------------- ------------ -------
US Taxable 100% $230.00
Intl Taxable 50% $65.93
Tax-Exempt 50% $65.93
Bonds Tax-Deferred 100% $226.80
The percentage refers to the percentage of the asset class printed
in the first column across account types. Please see lak whatif
section as well.
When lak whatif
command is used to test out hypothetical
changes to the portfolio, lak list whatifs
lists all the hypothetical
changes made to the portfolio. If there are no changes, the output is empty.
For example:
$ lak list whatifs
# Empty output as no whatifs are set.
# Hypothetically move $10 from VTI to VXUS in the taxable account.
$ lak whatif asset -a 'VTI' -10 asset -a 'VXUS' -t 'Tax' 10
$ lak list whatifs
Account Asset Delta
-------------- -------------------------------------------------------- -------
Schwab Taxable Vanguard Total Stock Market Index Fund ETF Shares -$10.00
Schwab Taxable Vanguard Total International Stock Index Fund ETF Shares +$10.00
This command lists all the checkpoints that were saved for a portfolio (e.g.
by using the lak add checkpoint
command).
$ lak list checkpoints --help
Usage: lak list checkpoints [OPTIONS]
Prints the portfolio's saved checkpoints.
Options:
-b, --begin DATE Start printing the checkpoints from this date (Format:
YYYY/MM/DD). If not provided, defaults to earliest date
for which a checkpoint exists.
-e, --end DATE Stop printing the checkpoints at this date (Format:
YYYY/MM/DD). If not provided, defaults to the latest date
for which a checkpoint exists.
--help Show this message and exit.
A sample output for this command looks like:
$ lak list checkpoints
Date Portfolio Value Inflow Outflow
---------- ----------------- -------- ---------
2021/01/03 $550.00 $0.00 $0.00
2021/12/08 $587.39 $10.00 $100.00
2022/01/22 $564.89 $0.00 $0.00
In addition to the portfolio value, this command lists the inflows (money added to the portfolio) or outflows (money removed from the portfolio) on different dates.
This command is used to print information about portfolio performance based on the checkpoints that were previously saved. A sample output for this command looks like:
$ lak list performance
Period Inflows Outflows Portfolio Change Change % IRR
-------- --------- ---------- ------------------ ---------- -----
3 Months $10.00 $100.00 -$95.59 -14% -4%
6 Months $10.00 $100.00 -$61.77 -10% 10%
1 Year $10.00 $100.00 +$7.75 1% 18%
Overall $10.00 $100.00 +$14.89 3% 18%
This command lists the portfolio inflows and outflows, change in the portfolio value and performance stats for different time periods. The last column (IRR) refers to the Internal Rate of Return of the portfolio.
This command is useful to print detailed information about parts of the portfolio (e.g. account or asset). Here are few examples:
$ lak info --help
Usage: lak info [OPTIONS] COMMAND1 [ARGS]... [COMMAND2 [ARGS]...]...
Print detailed information about parts of the portfolio.
Options:
--help Show this message and exit.
Commands:
account Print details of an account.
asset Print details of an asset.
performance Print detailed stats about portfolio's performance.
$ lak info account --help
Usage: lak info account [OPTIONS]
Print details of an account.
Options:
-t, --account substr Print info about the account that matches this
substring [required]
--help Show this message and exit.
# Don't need to list the whole name, as long as substr matches a unique account.
$ lak info account -t Sch
Name: Schwab Taxable
Type: Taxable
Total: $295.93
$ lak info asset --help
Usage: lak info asset [OPTIONS]
Print details of an asset.
Options:
-a, --asset substr Print info about the asset that matches this substring
[required]
-t, --account substr If the asset name is not unique across the portfolio,
an optional substring to specify the account to which
the asset belongs.
--help Show this message and exit.
# The short name of an asset can also be specified.
$ lak info asset -a VTI
Ticker: VTI
Name: Vanguard Total Stock Market Index Fund ETF Shares
Asset Class Mapping: US 100%
Value: $230.00
Price: $230.00
Tax lots:
Date Quantity Cost Gain Gain%
---------- --------- ------- ------ -------
2021/07/31 1 $226.00 +$4.00 2%
# It can also match a part of the full asset name as long as it is unique
$ lak info asset -a 'Total Sto'
Ticker: VTI
Name: Vanguard Total Stock Market Index Fund ETF Shares
Asset Class Mapping: US 100%
Value: $230.00
Price: $230.00
Tax lots:
Date Quantity Cost Gain Gain%
---------- --------- ------- ------ -------
2021/07/31 1 $226.00 +$4.00 2%
# If the asset is not unique across the portfolio, the account name
# has to be specified.
$ lak info asset -a VXUS -t Schwab
Ticker: VXUS
Name: Vanguard Total International Stock Index Fund ETF Shares
Asset Class Mapping: Intl 100%
Value: $65.93
Price: $65.93
Tax lots:
Date Quantity Cost Gain Gain%
---------- --------- ------ ------ -------
2021/07/31 1 $64.94 +$0.99 2%
If the portfolio has saved checkpoints (created via the lak add checkpoint
command), lak info performance
can be used to print
detailed stats about the perfolio's performance for different time periods:
$ lak info performance --help
Usage: lak info performance [OPTIONS]
Print detailed stats about portfolio's performance.
Options:
-b, --begin DATE Begining date from which to start computing performance
stats (Format: YYYY/MM/DD). If not provided, defaults to
the earliest possible date.
-e, --end DATE Ending date at which to stop computing performance stats
(Format: YYYY/MM/DD). If not provided, defaults to today.
--help Show this message and exit.
# If there is no checkpoint for the date specified, the value of the portfolio
# on that date is simply interpolated based on the two checkpoints surrounding
# it.
$ lak info performance -b 2021/06/06
Start date 2021/06/06
End date 2022/01/22
Beginning balance $607.87
Ending balance $564.89
Inflows $10.00
Outflows $100.00
Portfolio growth -$42.98
Market growth +$47.02
Portfolio growth % -7%
Internal Rate of Return 13%
Just like the lak list
command, lak info
command can be chained:
$ lak info asset -a 'VTI' asset -a 'VBMFX'
Ticker: VTI
Name: Vanguard Total Stock Market Index Fund ETF Shares
Asset Class Mapping: US 100%
Value: $230.00
Price: $230.00
Tax lots:
Date Quantity Cost Gain Gain%
---------- --------- ------- ------ -------
2021/07/31 1 $226.00 +$4.00 2%
Ticker: VBMFX
Name: Vanguard Total Bond Market Index Fund Investor Shares
Asset Class Mapping: Bonds 100%
Value: $226.80
Price: $11.34
This command is useful to run hypothetical whatif scenarios on a
portfolio without actually making those changes. After specifying
the changes via the lak whatif
command, all the lak
commands
(lak list aa
, lak list al
, etc.)
behave as if those changes were actually made to the portfolio.
To warn the user, some commands print a warning at the top indicating
that hypothetical whatifs are set.
These whatifs are ignored for the purposes of creating and saving checkpoints
(e.g. with lak add checkpoint
).
Just the like the lak info
command, lak whatif
command take either
account
or asset
as a sub-command:
$ lak whatif --help
Usage: lak whatif [OPTIONS] COMMAND1 [ARGS]... [COMMAND2 [ARGS]...]...
Run hypothetical what if scenarios by modifying the total value of an
account or asset. This is useful to see how the asset allocation or location
will change if you make these changes. Once you are done playing around with
the hypothetical changes, you can reset them all by using the --reset flag.
Options:
-r, --reset Reset all hypothetical whatif amounts.
--help Show this message and exit.
Commands:
account Run hypothetical what if scenario on an account.
asset Run hypothetical what if scenario on an asset.
To see what happens to the asset allocation if we sell $50 worth of VTI:
$ lak list aa --asset-class US,Intl,Bonds
Class Actual% Desired% Value Difference
------- --------- ---------- ------- ------------
US 39% 36% $230.00 -$18.08
Intl 22% 24% $131.86 +$9.42
Bonds 39% 40% $226.80 +$8.66
$ lak whatif asset -a VTI -50
$ lak list aa --asset-class US,Intl,Bonds
Warning: Hypothetical what ifs are set.
Class Actual% Desired% Value Difference
------- --------- ---------- ------- ------------
US 33% 36% $180.00 +$13.92
Intl 24% 24% $131.86 -$2.58
Bonds 42% 40% $226.80 -$11.34
We see that the actual allocation of US asset class decreased from
39% to 33% with those changes. Note the warning on top of the second
lak list aa
command.
lak list whatifs
can be used to check which whatifs are set:
$ lak list whatifs
Account Cash
-------------- -------
Schwab Taxable +$50.00
Account Asset Delta
-------------- ------------------------------------------------- -------
Schwab Taxable Vanguard Total Stock Market Index Fund ETF Shares -$50.00
We see that selling $50 worth of VTI didn't remove the money from the
portfolio. It simply shows up in the account as extra cash (so lak list total
will not show any difference in the total value of the portfolio).
lak whatif account
can be used to remove the extra cash from the
portfolio:
$ lak whatif account -t Schwab -50
$ lak list whatifs
Account Asset Delta
-------------- ------------------------------------------------- -------
Schwab Taxable Vanguard Total Stock Market Index Fund ETF Shares -$50.00
lak whatif -r
is a shortcut to reset and delete all whatif that are set.
This command can be chained to specify multiple whatif
commands. For example,
to reset all existing whatifs and move $50 from VTI to VXUS:
$ lak whatif -r asset -a VTI -50 asset -a VXUS -t Taxable 50
$ lak list whatifs
Account Asset Delta
-------------- -------------------------------------------------------- -------
Schwab Taxable Vanguard Total Stock Market Index Fund ETF Shares -$50.00
Schwab Taxable Vanguard Total International Stock Index Fund ETF Shares +$50.00
This command is used to analyze the portfolio:
$ lak analyze --help
Usage: lak analyze [OPTIONS] COMMAND1 [ARGS]... [COMMAND2 [ARGS]...]...
Analyze the portfolio.
Options:
--help Show this message and exit.
Commands:
allocate Allocates any unallocated cash in an account to assets.
rebalance Shows if any asset classes need to be rebalanced based on a...
tlh Shows which tax lots can be Tax-loss harvested (TLH).
$ lak analyze allocate --help
Usage: lak analyze allocate [OPTIONS]
Allocates any unallocated cash in an account to assets. If an account has
any unallocated cash (aka what if) then this command allocates that cash to
the assets in the account. This allocation is done with the goal of
minimizing the relative ratio of actual allocation to the desired ratio of
asset classes.
The unallocated cash in the account could be negative in which cash money is
removed from the assets.
This command modifies the portfolio by applying the resulting deltas to it
(similar to `lak whatif` command).
WARNING: This is a BETA feature and is subject to change or be removed.
Always sanity check the suggestions before acting on them.
Options:
-t, --account substr Allocate any cash in the account that matches
this substring. [required]
-e, --exclude-assets TEXT If provided, these assets in the account are not
allocated any cash. This is a comma separated
list of assets specified by their short names.
-r, --rebalance If not set (the default), money is either only
added (in case the acccount has any unallocated
cash) or only removed (in case the account has
negative unallocated cash) from the assets. If
set, money is both added and removed (as needed)
from the assets to minimize the relative
difference from the desired asset allocation.
--help Show this message and exit.
As an example, let's consider the example portfolio:
$ lak list assets aa
Account Asset Value
--------------- -------------------------------------------------------- -------
Schwab Taxable Vanguard Total Stock Market Index Fund ETF Shares $214.22
Schwab Taxable Vanguard Total International Stock Index Fund ETF Shares $57.01
Roth IRA Vanguard Total International Stock Index Fund ETF Shares $57.01
Vanguard 401(k) Vanguard Total Bond Market Index Fund Investor Shares $201.20
Class A% D% Class A% D% Actual% Desired% Value Difference
------- ---- ---- ------- ---- ---- --------- ---------- ------- ------------
Equity 62% 60% US 65% 60% 40% 36% $214.22 -$23.62
Intl 35% 40% 22% 24% $114.02 +$13.05
Bonds 38% 40% 38% 40% $201.20 +$10.58
Let's assume we wanted to invest an extra $20 in the Schwab Taxable
account
and wanted to know which asset to allocate the cash to. Let's first tell
lakshmi
that we have extra cash in an account:
$ lak whatif account -t 'Taxable' 20
After that we can ask it to allocate the cash:
$ lak analyze allocate -t 'Taxable'
Asset Delta
------- -------
VTI +$0.00
VXUS +$20.00
$ lak list whatifs aa
Account Asset Delta
-------------- -------------------------------------------------------- -------
Schwab Taxable Vanguard Total International Stock Index Fund ETF Shares +$20.00
Class A% D% Class A% D% Actual% Desired% Value Difference
------- ---- ---- ------- ---- ---- --------- ---------- ------- ------------
Equity 63% 60% US 62% 60% 39% 36% $214.22 -$16.42
Intl 38% 40% 24% 24% $134.02 -$2.15
Bonds 37% 40% 37% 40% $201.20 +$18.58
# Let's reset the whatifs
$ lak whatif -r
We can also use the same command to see how to rebalance within an account. Let's asssume we wanted to rebalance the portfolio by only selling & buying assets in the Schwab account. (This is a made up example. In most cases, one would want to avoid rebalancing in a taxable account. A better account to rebalance would be a 401(K) or Roth as there are no tax consequences for doing so.)
$ lak list aa
Class A% D% Class A% D% Actual% Desired% Value Difference
------- ---- ---- ------- ---- ---- --------- ---------- ------- ------------
Equity 62% 60% US 65% 60% 40% 36% $214.22 -$23.62
Intl 35% 40% 22% 24% $114.02 +$13.05
Bonds 38% 40% 38% 40% $201.20 +$10.58
$ lak analyze allocate -t 'Taxable' -r
Asset Delta
------- -------
VTI -$16.30
VXUS +$16.30
$ lak list aa
Warning: Hypothetical what ifs are set.
Class A% D% Class A% D% Actual% Desired% Value Difference
------- ---- ---- ------- ---- ---- --------- ---------- ------- ------------
Equity 62% 60% US 60% 60% 37% 36% $197.92 -$7.32
Intl 40% 40% 25% 24% $130.32 -$3.25
Bonds 38% 40% 38% 40% $201.20 +$10.58
$ lak analyze rebalance --help
Usage: lak analyze rebalance [OPTIONS]
Shows if any asset classes need to be rebalanced based on a band based
rebalancing scheme. For more information, please refer to
https://www.whitecoatinvestor.com/rebalancing-the-525-rule/.
Options:
-a, --max-abs-percentage FLOAT Max absolute difference before rebalancing.
[default: 5]
-r, --max-relative-percentage FLOAT
The max relative difference before
rebalancing. [default: 25]
--help Show this message and exit.
The rebalance
command only shows asset classes that don't fall within
the rebalancing bands. If all asset classes are within the bands, it prints
a message to that effect:
$ lak analyze rebalance
Portfolio Asset allocation within bounds.
$ lak analyze tlh --help
Usage: lak analyze tlh [OPTIONS]
Shows which tax lots can be Tax-loss harvested (TLH).
Options:
-p, --max-percentage FLOAT The max percentage loss for each lot before
TLHing. [default: 10]
-d, --max-dollars INTEGER The max absolute loss for an asset (across all
tax lots) before TLHing.
--help Show this message and exit.
A word of caution about the tlh
command: This command assumes that
specific share identification is picked as the investing accounting
method. Currently, it also doesn't account for
wash sales, which could
be problematic. Taxation is a complex topic and users are strongly
advised to do their own research before using this tool.
This command is used to edit various parts of the portfolio. The
portfolio or the performance file can be
directly edited if so desired,
but lak edit
makes it easier to directly modify the relevant
parts of the portfolio file.
$ lak edit --help
Usage: lak edit [OPTIONS] COMMAND [ARGS]...
Edit parts of the portfolio.
Options:
--help Show this message and exit.
Commands:
account Edit an account in the portfolio.
asset Edit an asset in the portfolio.
assetclass Edit the Asset classes and the desired asset allocation.
checkpoint Edit a protfolio's checkpoint.
For example, to edit the Schwab taxable account:
$ lak edit account -t Taxable
This opens up an editor with:
Name: Schwab Taxable
Account Type: Taxable
# # Lines starting with "#" are ignored and an empty message aborts this command.
# # An Account represents a collection of Assets (e.g. ETFs or Funds)
#
# # Name of the account, must be unique among all accounts in the portfolio.
# Name: Unique-name-for-account
#
# # Type of the account, e.g. Taxable, Tax-Exempt, Tax-Deferred, etc. This
# # name is used to group accounts when listing the Asset Location with
# # the 'lak list al' command.
# Account Type: Tax-Exempt
#
Every lak edit
sub-commands prints a similar (commented out) help message
at the bottom.
If no edits are made or an empty message is provided (i.e. by deleting
all the lines), the command is aborted. If there are any errors in the
file, lak edit
prints the error, and prompts the user to re-edit the
file.
lak edit checkpoint
command is used to edit previously saved checkpoints or
to add new checkpoint in-between two saved checkpoints. This is useful for
adding new information (e.g. missing cashflows) retroactively to the portfolio.
For example,
$ lak list checkpoints
Date Portfolio Value Inflow Outflow
---------- ----------------- -------- ---------
2021/01/03 $550.00 $0.00 $0.00
2021/12/08 $587.39 $10.00 $100.00
2022/01/22 $564.89 $0.00 $0.00
$ lak edit checkpoint -d 2021/11/11
# This will open up editor with checkpoint for date 2021/11/11 with the
# portfolio value pre-filled for that checkpoint by interpolating the portfolio
# values from 2021/01/03 and 2021/12/08.
This command allows the user to delete accounts, assets or checkpoints from the portfolio:
$ lak delete --help
Usage: lak delete [OPTIONS] COMMAND [ARGS]...
Delete different entities from the portfolio.
Options:
--help Show this message and exit.
Commands:
account Delete an account from the portfolio.
asset Delete an asset from the portfolio.
checkpoint Delete checkpoint for a given date.
lak delete
sub-commands prompt the user to confirm if they want to delete
the specified entity before actually deleting it. This can be skipped via
the --yes
flag.