4.8 KiB
Future Work
CLI options command UX
The options command auto-expands only the nearest monthly expiration and
lists others collapsed. Reconsider the interaction model — e.g. allow
specifying an expiration date, showing all monthlies expanded by default,
or filtering by strategy (covered calls, spreads).
Risk-free rate maintenance
T-bill rates are hardcoded in src/analytics/risk.zig as a year-by-year table
(source: FRED series DTB3). Each trailing period uses the average rate over its
date range. The table includes update instructions as doc comments.
Action needed annually: Update the current year's rate mid-year, finalize
the prior year's rate in January. See the curl commands in the tbill_rates
doc comment.
CLI/TUI code review (lower priority)
No review has been done on these files. They are presentation-layer code and not part of the reusable library API.
TUI:
src/tui.zigsrc/tui/chart.zigsrc/tui/keybinds.zigsrc/tui/theme.zig
Commands:
src/commands/common.zigsrc/commands/analysis.zigsrc/commands/cache.zigsrc/commands/divs.zigsrc/commands/earnings.zigsrc/commands/enrich.zigsrc/commands/etf.zigsrc/commands/history.zigsrc/commands/lookup.zigsrc/commands/options.zigsrc/commands/perf.zigsrc/commands/portfolio.zigsrc/commands/quote.zigsrc/commands/splits.zig
TUI: toggle to last symbol keybind
Add a single-key toggle that flips between the current symbol and the
previously selected one (like cd - in bash or Ctrl+^ in vim). Store
last_symbol on App; on symbol change, stash the previous. The toggle
key swaps current and last. Works on any tab — particularly useful for
eyeball-comparing performance/risk data between two symbols.
Fix enrich command for international funds
deriveMetadata in src/commands/enrich.zig misclassifies international ETFs:
-
geouses Alpha Vantage'sCountryfield, which is the fund issuer's domicile (USA for all US-listed ETFs), not the fund's investment geography. Every US-domiciled international fund getsgeo::US. -
asset_classshort-circuits to"ETF"whenasset_type == "ETF", or falls through to a US-market-cap heuristic that always produces"US Large Cap"/"US Mid Cap"/"US Small Cap".
Known misclassified tickers (all came back as geo::US, asset_class::US Large Cap):
- FRDM — Freedom 100 Emerging Markets ETF → should be
geo::Emerging Markets, asset_class::Emerging Markets - HFXI — NYLI FTSE International Equity Currency Neutral ETF → should be
geo::International Developed, asset_class::International Developed - IDMO — Invesco S&P International Developed Momentum ETF → should be
geo::International Developed, asset_class::International Developed - IVLU — iShares MSCI International Developed Value Factor ETF → should be
geo::International Developed, asset_class::International Developed
The Alpha Vantage OVERVIEW endpoint doesn't provide fund geography data.
Options: use the ETF_PROFILE holdings/country data to infer geography, parse
the fund name for keywords ("International", "Emerging", "ex-US"), or accept
that enrich is a scaffold and emit a # TODO comment for ETFs instead of
silently misclassifying.
Market-aware cache TTL for daily candles
Daily candle TTL is currently 23h45m, but candle data only becomes meaningful after the market close. Investigate keying the cache freshness to ~4:30 PM Eastern rather than a rolling window. This would avoid unnecessary refetches during the trading day and ensure a fetch shortly after close gets fresh data. Probably alleviated by the cron job approach.
On-demand server-side fetch for new symbols
Currently the server's SRF endpoints (/candles, /dividends, etc.) are pure
cache reads — they 404 if the data isn't already on disk. New symbols only get
populated when added to the portfolio and picked up by the next cron refresh.
Consider: on a cache miss, instead of blocking the HTTP response with a multi-second provider fetch, kick off an async background fetch (or just auto-add the symbol to the portfolio) and return 404 as usual. The next request — or the next cron run — would then have the data. This gives "instant-ish gratification" for new symbols without the downsides of synchronous fetch-on-miss (latency, rate limit contention, unbounded cache growth from arbitrary tickers).
Note that this process doesn't do anything to eliminate all the API keys that are necessary for a fully functioning system. A more aggressive view would be to treat ZFIN_SERVER as a 100% source of record, but that would introduce some opacity to the process as we wait for candles (for example) to populate. This could be solved on the server by spawning a thread to fetch the data, then returning 202 Accepted, which could then be polled client side. Maybe this is a better long term approach?