diff --git a/TODO.md b/TODO.md index 250aad2..479b37a 100644 --- a/TODO.md +++ b/TODO.md @@ -4,14 +4,44 @@ - Configurable return cap per position (default: none; cap outliers like NVDA) - Configurable MIN period selection (currently 3Y/5Y/10Y, exclude 1Y) -- Life events in `projections.srf`: Social Security income, college costs, pensions -- "Not Retired Yet" mode: contributions until retirement date -- Multiple spending models (Bernicke, percentage-of-remaining) +- "Not Retired Yet" mode: accumulation phase with contributions before retirement. + Separate from life events — the simulation has two distinct phases: accumulation + (base spending = 0, contributions applied) and distribution (searched-for withdrawal + + spending model). Config: `retirement_age::60` or `retirement_in::10`, plus + `annual_contribution::100000`. Safe withdrawal search only applies to the + distribution phase. Chart shows portfolio growing during accumulation, peaking + at retirement, then drawing down. +- Multiple spending models: flat (current), decreasing (1-2% real annual decrease, + Blanchett "spending smile"). Late-life healthcare better modeled as a life event. - Configurable benchmark symbols (currently hardcoded SPY + AGG) -- Age-based horizons from birthdates in projections.srf -- Weekly tracking history (portfolio value + retirement date time series) -- Kitty graphics percentile band chart (currently braille only) - Unclassified position handling in allocation split (warn user) +- Historical projection comparison: re-run projections from any past snapshot date, + overlay actual portfolio trajectory from subsequent snapshots onto the projected + percentile bands. Shows how reality tracked against the model. Data is already + available in history/*.srf snapshots — just need to load a historical portfolio + value and re-run `computePercentileBands` with that starting point, then plot + actual values from later snapshots as a line overlaid on the bands. + +## Earnings: GAAP vs adjusted EPS + limited history + +Two issues with the current Finnhub earnings implementation: + +1. **Wrong EPS type:** Finnhub's `/calendar/earnings` and `/stock/earnings` endpoints + both return GAAP diluted EPS. The analyst consensus estimates (epsEstimate) are + based on adjusted/non-GAAP EPS. Comparing GAAP actual against adjusted estimate + produces bogus surprise figures. For Amazon Q1 2026: GAAP = $1.56, adjusted = $2.78. + The difference is stock-based compensation and other non-cash items. + +2. **Limited history:** `/calendar/earnings` returns only 1-2 near-term events. + `/stock/earnings` returns only 4 quarters. Neither provides the 5+ years of + history the UI expects. + +**Fix options:** +- Alpha Vantage `EARNINGS` endpoint provides both reported (GAAP) and adjusted EPS + with full quarterly history. Would require adding AV as an earnings provider (AV + key already configured for ETF profiles). +- Accept Finnhub data and label it as GAAP, documenting the limitation. +- Use both: AV for history + adjusted EPS, Finnhub calendar for next-quarter dates. ## Analysis account/asset-class total mismatch