fix misleading refresh and total-return docs

This commit is contained in:
Emil Lerch 2026-08-19 15:11:20 -07:00
parent f39133819f
commit 65fefdb566
Signed by: lobo
GPG key ID: A7B62D657EF764F8
3 changed files with 46 additions and 10 deletions

View file

@ -19,10 +19,25 @@ Two columns show up throughout zfin:
3-Year Return: 20.75% 22.22% ann. 3-Year Return: 20.75% 22.22% ann.
``` ```
Total return needs dividend history, which comes from Polygon -- so it Total return is computed two ways, and zfin reports whichever comes out
requires `POLYGON_API_KEY`. Without it, you still get price-only higher per period:
returns. For a dividend payer like SCHD the gap between the two columns
is large; for a non-payer it's near zero. - **Dividend reinvestment** -- walk the dividend history, buy more shares
at each ex-date's close, compound. Exact, but only as complete as the
dividend records, which come from Polygon -- so this path wants
`POLYGON_API_KEY`.
- **Adjusted close** -- providers publish an `adj_close` that already
bakes dividends in. No dividend history needed, but it is only as
current as the last full price-history download (see
[Incremental candle updates](caching.md#incremental-candle-updates)).
Both failure modes -- a missing dividend record, a stale adjustment --
understate the return, never overstate it, which is why taking the higher
of the two is safe rather than arbitrary. So without `POLYGON_API_KEY`
you still get a genuine total return, just via the second path; the gap
you'd see is at most a distribution or two, not the whole yield. For a
dividend payer like SCHD the gap between the price-only and total-return
columns is large; for a non-payer it's near zero.
## Annualized (CAGR) ## Annualized (CAGR)

View file

@ -17,11 +17,29 @@ zfin --refresh-data=force perf VTI
zfin --refresh-data=never analysis zfin --refresh-data=never analysis
``` ```
| Value | Behavior | | Value | Behavior |
|------------------|---------------------------------------------------------------------------------------------------------------| |------------------|----------------------------------------------------------------------------------------------------------------|
| `auto` (default) | Respect each data type's cache TTL; fetch only what's stale. | | `auto` (default) | Respect each data type's cache TTL; fetch only what's stale. |
| `force` | Re-fetch every symbol regardless of freshness. Use after a market close, or when you suspect bad cached data. | | `force` | Re-ask providers regardless of freshness. Use after a market close, or when a fetch seems to have been missed. |
| `never` | Serve cache contents only; make no network calls. True offline mode. | | `never` | Serve cache contents only; make no network calls. True offline mode. |
### `force` tops up price history, it does not rebuild it
Worth knowing before you reach for it: for daily candles, `force` skips
the TTL and asks the provider for anything newer than the last cached
bar. It does **not** re-download the series. So if you suspect the
*existing* bars are wrong rather than merely incomplete, `force` will
not help -- it appends and moves on.
That case is handled automatically now. When a dividend or split goes ex,
the bars behind it need their adjusted closes marked down, and zfin
re-downloads that symbol's full history to pick up the corrected values
on its own -- see
[Incremental candle updates](../explanation/caching.md#incremental-candle-updates).
`zfin diagnose SYMBOL` says whether one is pending.
`zfin cache clear` remains the blunt instrument if you want to discard
everything and start over.
## Working offline ## Working offline
@ -66,7 +84,8 @@ zfin cache clear # delete all cached data
`cache clear` is safe -- everything re-fetches on the next run (subject `cache clear` is safe -- everything re-fetches on the next run (subject
to provider rate limits). Reach for it only when you suspect corrupt to provider rate limits). Reach for it only when you suspect corrupt
cached data; normal staleness is handled by `auto`. See cached data; normal staleness is handled by `auto`, and a stale
adjustment basis repairs itself. See
[`zfin cache`](../reference/cli/cache.md). [`zfin cache`](../reference/cli/cache.md).
## See also ## See also

View file

@ -50,6 +50,8 @@ pub const meta: framework.Meta = .{
\\ adj basis how current the cached adj_close values are, against the \\ adj basis how current the cached adj_close values are, against the
\\ newest dividend or split that has already gone ex \\ newest dividend or split that has already gone ex
\\ peers newest bar held by other symbols of the same kind \\ peers newest bar held by other symbols of the same kind
\\ tracked whether a normal run fetches this symbol at all, or it is
\\ only pulled on demand (a projections benchmark, say)
\\ server what ZFIN_SERVER offers, whether it is ahead or behind, and \\ server what ZFIN_SERVER offers, whether it is ahead or behind, and
\\ whether it refreshes this symbol at all \\ whether it refreshes this symbol at all
\\ provider what the upstream provider actually has right now \\ provider what the upstream provider actually has right now