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.
```
Total return needs dividend history, which comes from Polygon -- so it
requires `POLYGON_API_KEY`. Without it, you still get price-only
returns. For a dividend payer like SCHD the gap between the two columns
is large; for a non-payer it's near zero.
Total return is computed two ways, and zfin reports whichever comes out
higher per period:
- **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)

View file

@ -17,11 +17,29 @@ zfin --refresh-data=force perf VTI
zfin --refresh-data=never analysis
```
| Value | Behavior |
|------------------|---------------------------------------------------------------------------------------------------------------|
| `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. |
| `never` | Serve cache contents only; make no network calls. True offline mode. |
| Value | Behavior |
|------------------|----------------------------------------------------------------------------------------------------------------|
| `auto` (default) | Respect each data type's cache TTL; fetch only what's stale. |
| `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. |
### `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
@ -66,7 +84,8 @@ zfin cache clear # delete all cached data
`cache clear` is safe -- everything re-fetches on the next run (subject
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).
## 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
\\ newest dividend or split that has already gone ex
\\ 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
\\ whether it refreshes this symbol at all
\\ provider what the upstream provider actually has right now