diff --git a/TODO.md b/TODO.md index e598626..b8675b5 100644 --- a/TODO.md +++ b/TODO.md @@ -105,3 +105,48 @@ 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? + +## Per-account covered call adjustment + +`adjustForCoveredCalls` in `valuation.zig` operates on portfolio-wide aggregated +allocations. It matches sold calls against total underlying shares across all +accounts. This is wrong — calls in one account can only cover shares in that +same account. If NVDA calls are sold in Emil IRA, they shouldn't cap NVDA +shares held in Joint trust. + +Fixing this means restructuring `portfolioSummary`, since `Allocation` is +currently account-agnostic. Approach: compute per-account reductions using +`positionsForAccount` + account-filtered option lots, then sum into +portfolio-wide reductions. Each account's reduction capped by that account's +shares, not the global total. + +Low priority — naked calls are rare, and calls are typically in the same +account as the underlying. + +## Covered call adjustment optimization + +`adjustForCoveredCalls` has a nested loop — for each allocation, it iterates +all lots to find matching option contracts. O(N*M) is fine for personal +portfolios (<1000 lots). Pre-indexing options by underlying would help if +someone had a very large options-heavy portfolio. + +## Mixed price_ratio grouping + +`Position` grouping in `portfolio.zig` keys on `priceSymbol` alone. Lots with +different `price_ratio` values sharing the same `priceSymbol` get incorrectly +merged (e.g. investor vs institutional shares of the same fund). Should key +on `(priceSymbol, price_ratio)` tuple. Edge case — most people don't hold +both share classes simultaneously. + +## HTTP connection pooling + +Parallel server sync in `loadAllPrices` spawns up to 8 threads, each with its +own HTTP connection. Could reuse connections to reduce TCP handshake overhead. +Only matters with very large portfolios (100+ symbols) hitting ZFIN_SERVER. +8 concurrent connections is fine for now. + +## Streaming cache deserialization + +Cache store reads entire files into memory (`readFileAlloc` with 50MB limit). +For portfolios with 10+ years of daily candles, this could use significant +memory. Keep current approach unless memory becomes a real problem.