# 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: - [`contributions`](track-contributions.md) attributes what changed between two commits to *new money* vs. *market movement*. It works on the raw share/lot changes in the diff. - [`compare`](../reference/cli/compare.md) and [`audit`](audit-against-brokerage.md) read 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`](snapshots-and-history.md) 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`](../reference/config/metadata-srf.md#stock-split-adjustment): ```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`](../reference/cli/splits.md): ```bash 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_through` to 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_through` to 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 `shares` because > 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: ```bash zfin audit ``` Once set, [`zfin portfolio`](../reference/cli/portfolio.md) shows the effective (split-adjusted) share count and the correct market value, while your files stay untouched. ## Next steps - [`metadata.srf` reference](../reference/config/metadata-srf.md#stock-split-adjustment) -- the field's exact semantics. - [Track contributions](track-contributions.md) -- why the git diff must stay honest. - [Snapshots and history](snapshots-and-history.md) -- the frozen records a restate would desync. --- [Previous: Snapshots and history](snapshots-and-history.md) | [Next: Plan for retirement](plan-retirement.md) | [Documentation home](../README.md)