5.2 KiB
Handle a stock split
Goal: keep your holdings correct through a stock split without breaking the history that zfin's other commands rely on.
The one rule: when a stock you hold splits, do not edit the share
count on your existing lot. Leave the lot exactly as you transacted
it, and tell zfin about the split with one line in metadata.srf. zfin
does the rest on read.
Why not just change the share count?
It seems natural: NVDA does a 10:1 split, your 100 shares become 1,000,
so you open portfolio.srf and change shares:num:100 to
shares:num:1000. Don't -- here is what that quietly breaks.
Your portfolio file is history, and zfin reads the history, not just
the latest version. If you are utilizing all zfin features, portfolio.srf
lives in git, and several commands diff past commits of it:
contributionsattributes what changed between two commits to new money vs. market movement. It works on the raw share/lot changes in the diff.compareandauditread git history the same way.
A split changes your share count but not your money: 100 shares
at $400 and 1,000 shares at $40 are the same $40,000. But if you edit the
lot from 100 to 1,000 and commit, the git diff shows +900 shares.
contributions cannot tell that apart from you buying 900 shares, so
it reports a large phantom contribution that never happened -- and it
is now baked into your commit history permanently.
Snapshots make it worse. zfin snapshot
writes immutable, point-in-time records of your portfolio under
history/. A snapshot taken before your edit recorded 100 shares;
after the edit, your live file says 1,000. The two no longer agree, and
you cannot fix the old snapshot -- it is a frozen record of a past
day, and compare / history read it as-is.
Both git history and snapshots are append-only truth: undoing the damage means rewriting git history (dangerous) or hand-editing frozen snapshot files (error-prone). So the safe design is simple -- a split must never touch your recorded shares. It is a derivation, not an edit.
What to do instead
Leave the lot alone. Add a per-symbol splits_current_through date to
that symbol's row in
metadata.srf:
#!srfv1
symbol::NVDA,sector::Technology,geo::US,asset_class::US Large Cap,splits_current_through::2020-01-01
Set the date to when that symbol's recorded shares were last
accurate -- for a lot you entered as transacted, that is on or around
the purchase. zfin then applies every split after that date to compute
the effective (split-adjusted) share count on the fly. Your
portfolio.srf, git history, and snapshots stay exactly as transacted;
only the displayed and valued shares reflect the split.
You can see the split zfin will apply with
zfin splits:
zfin splits NVDA
Copying post-split numbers from your brokerage is fine
Brokerages do restate: after a split, Fidelity or Schwab show you the post-split share count and split-adjusted cost basis. Recording a lot from one of those statements is not the mistake above -- you are stating a holding as it stands today, not reaching back to rewrite a lot that already lived through the split in your file.
The only thing zfin needs to know is whether the split is already baked into the number you typed. The cutover date answers that:
- Shares entered as transacted (pre-split). The split happened after
you recorded them, so set
splits_current_throughto a date before the split. zfin applies it. - Shares copied post-split from a statement. The number already
includes the split, so set
splits_current_throughto the statement date (after the split). zfin leaves it alone instead of applying it twice.
Either way the rule holds: you never went back and edited an existing lot's shares. You either left it as transacted or recorded a fresh lot from a statement, and the cutover date tells zfin which.
Bright line: recording a lot from a post-split statement is fine. Reaching back to change an existing committed lot's
sharesbecause of a split is what corrupts your history. If you are tempted to edit a number that is already committed, set the cutover instead.
Verify
zfin audit's hygiene check lists any held symbol that has a
post-purchase split but no splits_current_through yet, under
Unhandled stock splits -- so you can see at a glance which rows still
need the line:
zfin audit
Once set, zfin portfolio shows the
effective (split-adjusted) share count and the correct market value,
while your files stay untouched.
Next steps
metadata.srfreference -- the field's exact semantics.- Track contributions -- why the git diff must stay honest.
- Snapshots and history -- the frozen records a restate would desync.
Previous: Snapshots and history | Next: Plan for retirement | Documentation home