4 KiB
Future Work
Yahoo Finance as primary quote source
Consider adding Yahoo Finance as the primary provider for real-time quotes, with a silent fallback to TwelveData. Yahoo is free and has no API key requirement, but the unofficial API is brittle and can break without notice. TwelveData would serve as the reliable backup when Yahoo is unavailable.
Covered call portfolio valuation
Portfolio value should account for sold call options. Shares covered by in-the-money calls should be valued at the strike price, not the market price.
Example: 500 shares of AMZN at $225, with 3 sold calls at $220 strike. 300 shares should be valued at $220 (covered), 200 shares at $225 (uncovered).
Human review of analytics modules
AI review complete; human review still needed for:
src/analytics/performance.zig— Morningstar-style trailing returnssrc/analytics/risk.zig— Sharpe, volatility, max drawdown, portfolio summarysrc/analytics/indicators.zig— SMA, Bollinger Bands, RSIsrc/models/classification.zig— Sector/geo/asset-class metadata parsing
Known issues from AI review:
risk.ziguses population variance (divides by n) instead of sample variance (n-1). Negligible with 252+ data points but technically wrong.
Risk-free rate maintenance
risk.zig default_risk_free_rate is currently 4.5% (T-bill proxy as of
early 2026). This is now a parameter to computeRisk with the default
exported as a public constant. Callers currently pass the default.
Action needed: When the Fed moves rates significantly, update
default_risk_free_rate in src/analytics/risk.zig. Eventually consider
making this a config value (env var or .env) so it doesn't require a rebuild.
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
Market-aware cache TTL for daily candles
Daily candle TTL is currently 24 hours, but candle data only becomes meaningful after the market close. Investigate keying the cache freshness to ~4:30 PM Eastern (or whenever TwelveData actually publishes the daily candle) rather than a rolling 24-hour window. This would avoid unnecessary refetches during the trading day and ensure a fetch shortly after close gets fresh data. I think that issue has been alleviated by the 23hr 45min plus cron job.
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 has a 100% record of reference, 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?