zfin/docs/guides/read-your-portfolio.md
Emil Lerch 74fc219afd
All checks were successful
Generic zig build / build (push) Successful in 5m48s
Generic zig build / publish-macos (push) Successful in 11s
Generic zig build / deploy (push) Successful in 23s
add docs/guides
2026-06-22 14:53:53 -07:00

7.7 KiB

Read your portfolio

Goal: make sense of what zfin shows you. This guide walks the five commands you'll reach for most -- portfolio, analysis, review, exposure, and perf -- and explains how to read each one.

Every example below runs against the bundled pre-retirement-both household, so you can follow along verbatim:

ZFIN_HOME=examples/pre-retirement-both zfin portfolio

(Dollar figures depend on live prices, so yours will differ.)

portfolio: positions and value

ZFIN_HOME=examples/pre-retirement-both zfin portfolio
Portfolio Summary (examples/pre-retirement-both/portfolio.srf)
========================================
  Value: $1,383,137.81  Cost: $658,837.01  Gain/Loss: +$724,300.80 (109.9%)
  Lots: 13 open, 0 closed    Positions: 5 symbols
  Historical:  1M: +3.2%  3M: +13.3%  1Y: +24.5%  3Y: +56.4%  5Y: +56.1%  10Y: +182.6%

  Symbol    Shares   Avg Cost      Price     Market Value      Gain/Loss   Weight ...
  VTI       2480.0    $138.35    $373.38      $925,982.40 +  $582,874.40    66.9%
    open      1100.0    $140.00                 $410,718.00 +  $256,718.00          2018-06-15 LT Pat 401k
    ...

How to read it:

  • The header line is your liquid total, total cost, and aggregate gain/loss.
  • Historical is the portfolio's blended price return over trailing windows -- a quick "how have my holdings done" gut check.
  • Each position shows aggregated shares, average cost, current price, market value, gain/loss, and weight. Indented open rows are the individual lots, tagged LT/ST (long/short-term holding period) and the account.
  • Cash is summarized by account at the bottom.

Manual-priced rows render in warning color so you know the price may be stale. Full output shape: zfin portfolio.

Covered calls

zfin values a written (short) call by capping the covered shares at the strike, rather than pricing the option contract -- it never looks up a live option quote. When the call is in-the-money (the stock trades above the strike), the covered shares are valued at the strike, since that's the price you'd be assigned at; an out-of-the-money call gets no adjustment, and an expired or closed call stops capping.

This differs from your brokerage, which tracks the call as its own line with its own mark-to-market gain/loss. Example: you hold 100 MSFT and wrote a $500 call. If MSFT trades at $510, zfin values those shares at $50,000 (100 x the $500 strike), not $51,000 (100 x $510) -- the $1,000 of upside above the strike now belongs to the call holder. A brokerage would instead show $51,000 of stock plus a separate, losing short-call position.

This is deliberate, and for a covered call used as an exit strategy it's the more useful number: the cap is the value you'll actually realize when the call assigns. Mark-to-market would understate it, because an in-the-money call also carries time value you'd only pay to buy it back -- which a let-it-assign writer never does. (At $510 the call might mark around $14, so a brokerage nets $496/share even though you'll realize the full $500 at assignment.) The flip side: zfin is built for covered-call and buy-write investors, not active option trading -- it deliberately doesn't track the live mark-to-market swings of contracts you intend to trade rather than hold to assignment.

analysis: allocation breakdowns

ZFIN_HOME=examples/pre-retirement-both zfin analysis

analysis answers "how is my money allocated?" along five axes: Asset Category, Sector, Geographic, By Account, and By Tax Type. Each bar is a share of your liquid total.

  By Tax Type
  Traditional (Pre-Tax)    █████████████████▋              58.9%  $815,290.06
  Taxable                  ██████▍                         21.6%  $299,010.60
  Roth (Post-Tax)          █████                           16.9%  $233,732.95
  HSA (Triple Tax-Free)    ▊                                2.5%  $35,104.20

The Sector and Asset Category axes need metadata.srf; the Tax Type axis needs accounts.srf. Anything missing classification lands under "Unclassified" / "Unknown."

Umbrella exposure

A personal umbrella insurance policy covers liability -- lawsuits and judgments -- above your auto/home limits, and you size it to the assets you'd need to protect. The last block estimates that target: how much of your liquid net worth is exposed to a civil judgment because it sits outside judgment-protected retirement accounts:

  Umbrella exposure
    Total liquid:                              $1,383,137.81
    Shielded (retirement accounts):            $1,084,127.21
    Exposed (taxable + non-shielded pre-tax):  $299,010.60 (21.6%)
                                               ↑ approximate umbrella target

The default rule treats anything that isn't taxable as shielded. Override per account with shielded:bool:false in accounts.srf -- IRA protection varies by state and isn't modeled automatically.

review: per-holding performance and risk

ZFIN_HOME=examples/pre-retirement-both zfin review

review is a dashboard: one row per holding with trailing returns, volatility, Sharpe ratio, max drawdown, and a taxable-percentage column, plus automated findings at the bottom.

  Symbol   Sector                   Wt%       1Y       3Y  ...   3Y-SR   10Y-SR   5Y-MaxDD    Tax%
  VTI      Diversified            66.9%   +30.2%   +23.3%  ...    1.29     0.90      24.8%   10.9%
  QQQ      Technology              3.5%   +43.1%   +29.3%  ...    1.41     1.16      32.6%    0.0%

  Findings (2 active, 0 acked, 0 resolved)
  ⚠️ VTI at 66.9% of liquid (warn at 50.0%, flag at 70.0%)
  ❌️ Diversified sector at 85.7% (warn at 60.0%, flag at 75.0%)

The findings flag concentration, sector dominance, volatility outliers, and tiny positions against configurable thresholds. The status icons at the top summarize which checks fired. See zfin review.

exposure: look-through to a single symbol

ZFIN_HOME=examples/pre-retirement-both zfin exposure SPY

exposure answers "how much of X do I really own?" -- combining direct holdings with look-through into the ETFs you hold (matched by CUSIP against each ETF's latest reported holdings):

Exposure to SPY  (examples/pre-retirement-both/portfolio.srf)
========================================
  Total exposure    17.3%     $238,956.80
    Direct          17.3%     $238,956.80
    Look-through     0.0%           $0.00

This is most interesting for an individual stock you also hold inside broad-market ETFs (e.g. checking your true NVDA exposure across VTI, SPY, and QQQ). See zfin exposure.

perf: trailing returns for one symbol

ZFIN_HOME=examples/pre-retirement-both zfin perf VTI

perf shows Morningstar-style trailing returns (price-only and total return), as-of the latest close and as-of the most recent month-end, plus risk metrics. For what "total return," "annualized," and "month-end" mean, see Returns and performance.

Where to go next


Previous: Map your accounts | Next: Track contributions | Documentation home