127 lines
6.4 KiB
Markdown
127 lines
6.4 KiB
Markdown
# `metadata.srf` reference
|
|
|
|
`metadata.srf` classifies each symbol by asset class, sector, and
|
|
geography so [`zfin analysis`](../cli/analysis.md) can produce
|
|
allocation breakdowns and [`zfin review`](../cli/review.md) can group
|
|
holdings by sector. zfin loads it from the same directory as the
|
|
resolved portfolio file.
|
|
|
|
It is optional, but without it the Asset Category / Sector / Geographic
|
|
breakdowns have nothing to group by. The fastest way to create one is
|
|
[`zfin enrich`](../cli/enrich.md); see
|
|
[Classify your holdings](../../guides/classify-holdings.md).
|
|
|
|
## File format
|
|
|
|
One record per `(symbol, allocation)` pair. A single-asset-class
|
|
security needs one line; a blended fund needs several lines that sum to
|
|
~100%.
|
|
|
|
```srf
|
|
#!srfv1
|
|
symbol::VTI,sector::Diversified,geo::US,asset_class::US Large Cap
|
|
symbol::AGG,sector::Bonds,geo::US,asset_class::Bonds
|
|
```
|
|
|
|
## Fields
|
|
|
|
| Field | Type | Required | Default | Description |
|
|
|--------------------------|--------|----------|-----------|-------------------------------------------------------------------------------------------------------------------------------|
|
|
| `symbol` | string | Yes | -- | Ticker or CUSIP. Must match `symbol::` (or `ticker::`) on a portfolio lot. |
|
|
| `name` | string | No | -- | Human-readable security name (e.g. "SPDR S&P 500 ETF Trust"). Shown where available; falls back to the symbol. |
|
|
| `asset_class` | string | No | -- | e.g. `US Large Cap`, `Bonds`, `International Developed`, `Emerging Markets`. |
|
|
| `sector` | string | No | -- | e.g. `Technology`, `Healthcare`, `Financials`, `Diversified`, `Bonds`. |
|
|
| `geo` | string | No | -- | e.g. `US`, `International Developed`, `Emerging Markets`. |
|
|
| `bucket` | string | No | (derived) | User-curated grouping label that overrides the auto-derived sector bucket for concentration/dominance checks (see below). |
|
|
| `pct` | number | No | `100` | Weight of this allocation line for the symbol. Use multiple lines for blended funds. |
|
|
| `splits_current_through` | date | No | (unset) | Per-symbol opt-in for automatic stock-split adjustment (`YYYY-MM-DD`). See [Stock split adjustment](#stock-split-adjustment). |
|
|
|
|
Cash and CD lots are classified as "Cash & CDs" automatically -- they
|
|
need no metadata entry.
|
|
|
|
## The `bucket` field
|
|
|
|
For concentration and sector-dominance analysis, zfin needs a
|
|
meaningful grouping label. It derives one automatically, but the
|
|
upstream `sector` can be uninformative -- ETF holdings data often tags
|
|
everything as the generic "Equity / Corporate." When several distinct
|
|
holdings collapse into one meaningless bucket, set `bucket::` yourself
|
|
to a label that actually distinguishes them. When `bucket` is unset,
|
|
zfin falls back through: `sector` (if it isn't a fund-decomposition
|
|
category) -> a composite `"<geo> <asset_class>"` -> `Unclassified`.
|
|
See [Classify your holdings](../../guides/classify-holdings.md#fixing-uninformative-sectors)
|
|
for a worked `bucket` example.
|
|
|
|
## Blended funds
|
|
|
|
For a target-date or balanced fund, add one line per asset class with
|
|
`pct:num:` weights summing to ~100:
|
|
|
|
```srf
|
|
#!srfv1
|
|
symbol::02315N600,asset_class::US Large Cap,pct:num:55
|
|
symbol::02315N600,asset_class::International Developed,pct:num:20
|
|
symbol::02315N600,asset_class::Bonds,pct:num:15
|
|
symbol::02315N600,asset_class::Emerging Markets,pct:num:10
|
|
```
|
|
|
|
## Stock split adjustment
|
|
|
|
Lots in [`portfolio.srf`](portfolio-srf.md) are immutable historical
|
|
records -- the share count and price exactly as transacted. zfin never
|
|
rewrites them for a stock split; instead it derives *effective*
|
|
(split-adjusted) shares on read, so a position held across a split is
|
|
valued correctly without you editing the file.
|
|
|
|
This adjustment is **opt-in, per symbol**. Add
|
|
`splits_current_through::YYYY-MM-DD` to a symbol's row to enable it for
|
|
that symbol:
|
|
|
|
```srf
|
|
#!srfv1
|
|
symbol::NVDA,sector::Technology,geo::US,asset_class::US Large Cap,splits_current_through::2024-01-01
|
|
```
|
|
|
|
The date is the point through which that symbol's recorded shares are
|
|
*already current*. zfin auto-applies any split that occurs **after** it;
|
|
splits on or before it are assumed already reflected in your recorded
|
|
shares. Set it to the date you last reconciled (or entered) that
|
|
holding:
|
|
|
|
- If you record lots **as transacted** (pre-split share counts), set the
|
|
cutover *before* the split so zfin applies it.
|
|
- If you entered a lot with **post-split** share counts -- common when
|
|
copying from a broker statement after the fact, e.g. an AMZN lot
|
|
entered after its 2022 20:1 split -- set the cutover *after* that split
|
|
so zfin does not double-apply it.
|
|
|
|
When the field is absent, split adjustment is **off** for that symbol --
|
|
identical to zfin's behavior before this feature existed. Split data
|
|
comes from the same feed as [`zfin splits`](../cli/splits.md).
|
|
|
|
[`zfin audit`](../cli/audit.md) lists held symbols that have a
|
|
post-purchase split but no `splits_current_through` yet (under
|
|
"Unhandled stock splits"), so you know which rows still need it.
|
|
|
|
## Example (from `examples/pre-retirement-both`)
|
|
|
|
```srf
|
|
#!srfv1
|
|
symbol::VTI,sector::Diversified,geo::US,asset_class::US Large Cap
|
|
symbol::SPY,sector::Diversified,geo::US,asset_class::US Large Cap
|
|
symbol::QQQ,sector::Technology,geo::US,asset_class::US Large Cap
|
|
symbol::SCHD,sector::Diversified,geo::US,asset_class::US Large Cap
|
|
symbol::AGG,sector::Bonds,geo::US,asset_class::Bonds
|
|
```
|
|
|
|
## See also
|
|
|
|
- [Classify your holdings](../../guides/classify-holdings.md) -- the walkthrough, including `enrich`.
|
|
- [`zfin enrich`](../cli/enrich.md) -- bootstrap this file from Wikidata + SEC EDGAR.
|
|
- [`zfin analysis`](../cli/analysis.md) -- the breakdowns this file feeds.
|
|
- [`zfin review`](../cli/review.md) -- the per-holding Sector column and grouping this file feeds.
|
|
- [`zfin audit`](../cli/audit.md) -- flags symbols with an unhandled split that need `splits_current_through`.
|
|
|
|
---
|
|
|
|
[Documentation home](../../README.md#reference)
|