101 lines
4.5 KiB
Markdown
101 lines
4.5 KiB
Markdown
# `zfin compare`
|
|
|
|
Compare your portfolio at two points in time: liquid totals,
|
|
per-symbol price moves, and contribution attribution.
|
|
|
|
```
|
|
Usage:
|
|
zfin compare <DATE> # compare DATE vs. live portfolio
|
|
zfin compare <DATE1> <DATE2> # compare two historical dates
|
|
```
|
|
|
|
Arguments can be given in any order; output always reads older ->
|
|
newer. Dates accept `YYYY-MM-DD` or relative shortcuts
|
|
(`1W`/`1M`/`1Q`/`1Y`). Historical dates resolve against your
|
|
`history/*-portfolio.srf` snapshots; on a missing date, `compare`
|
|
prints the nearest available dates and exits rather than snapping
|
|
silently.
|
|
|
|
## Options
|
|
|
|
| Flag | Effect |
|
|
|--------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------|
|
|
| `--projections` | Add projected-return and 99% safe-withdrawal deltas (adds ~1-2s per endpoint). |
|
|
| `--no-events` | With `--projections`, exclude life events. |
|
|
| `--snapshot-before <DATE>` / `--snapshot-after <DATE>` | Override a side's snapshot (`--snapshot-after live` for the current portfolio). |
|
|
| `--commit-before <SPEC>` / `--commit-after <SPEC>` | Pin the git commit for the attribution block (`HEAD`, `HEAD~N`, SHA, or `working`). Useful when a review date and its commit diverge. |
|
|
|
|
## Example
|
|
|
|
```bash
|
|
ZFIN_HOME=examples/post-retirement zfin compare 2024-04-01 2025-04-01
|
|
```
|
|
|
|
```
|
|
Portfolio comparison: 2024-04-01 -> 2025-04-01 (365 days)
|
|
|
|
Liquid: $2,350,000.00 -> $2,580,000.00 +$230,000.00 +9.79%
|
|
```
|
|
|
|
With symbols held on both dates, a per-symbol price-change table
|
|
appears, sorted by percentage move.
|
|
|
|
### Mixed share classes
|
|
|
|
A symbol can cover holdings in more than one share class -- for example
|
|
a direct-indexing sleeve, a 401(k) collective trust and plain retail
|
|
shares all priced through the same `ticker::` alias with different
|
|
`price_ratio` values. Those trade at different per-share prices, so the
|
|
group has no single price to show and the price columns render as
|
|
`—`. The percentage and dollar figures come from the change in market
|
|
value instead.
|
|
|
|
Whether that percentage is trustworthy depends on one thing: **did the
|
|
share count move?**
|
|
|
|
**Share count unchanged** -- the percentage is a real return, and the row
|
|
sorts inline with everything else. A group's value is its underlying
|
|
price times a fixed basket, so with the basket held still the change in
|
|
value *is* the change in price. You just don't get a per-share price
|
|
beside it:
|
|
|
|
```
|
|
SPYM — -> — +9.40% +$110,000.00
|
|
```
|
|
|
|
**Shares bought or sold** -- the figure now mixes market movement with
|
|
your own cash flow and there is no way to separate them. Those rows are
|
|
tallied separately, named in a footnote, and always sorted last so you
|
|
can disregard them as a block:
|
|
|
|
```
|
|
SPYM — -> — +30.69% +$419,605.63
|
|
18 gainers, 3 losers, 1 share count changed
|
|
SPYM: spans share classes AND the share count moved, so the figure is total value change - part market, part shares bought or sold.
|
|
```
|
|
|
|
In that second example much of the `+30.69%` is a retail purchase made
|
|
partway through the window, not market movement.
|
|
|
|
Ordinary (non-mixed) rows are never affected by this: their percentage is
|
|
a pure price ratio, so buying or selling during the window cannot
|
|
distort it.
|
|
|
|
One caveat the tool cannot detect: restating a `price_ratio` without
|
|
changing shares also breaks the equivalence, because the ratio itself is
|
|
not recorded in a snapshot. If you have just re-based a proxied holding,
|
|
treat percentages spanning that date with suspicion.
|
|
|
|
This split is a limitation of what snapshots record rather than a display
|
|
choice: `price_ratio` is folded into each lot's stored price and the
|
|
underlying base price is never written, so a single meaningful price for
|
|
the group cannot be reconstructed after the fact.
|
|
|
|
## See also
|
|
|
|
- [Snapshots and history](../../guides/snapshots-and-history.md)
|
|
- [`history`](history.md) -- the full timeline. [`contributions`](contributions.md) -- the attribution detail.
|
|
|
|
---
|
|
|
|
[CLI command reference](index.md)
|