mirror of
https://github.com/we-promise/sure.git
synced 2026-09-04 06:11:12 +00:00
* Fix SnapTrade holdings by using the /positions/all endpoint SnapTrade returns HTTP 410 Gone on /positions, /holdings and /options for apps registered after their 2026 cutoff, so newly connected accounts import their balance but never any holdings. The importer rescues the error and the sync still reports success, which makes it look like the brokerage simply holds nothing. Switch get_positions to the documented replacement, /positions/all, and teach the shared payload helpers to read its flat `instrument` object alongside the legacy nested `symbol.symbol` shape. Fixes #3029 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Filter unsupported instrument kinds before they reach the payload Derivatives skipped by HoldingsProcessor still landed in raw_holdings_payload, where calculate_holdings_value sums units * price over every entry. Any non-zero sum then displaces SnapTrade's own figure in calculate_total_balance, so an options-only account could report a balance derived from per-contract units against a per-share price. Move the denylist to Provider::Snaptrade#get_positions so unsupported kinds never enter the payload at all, keeping holdings, balance, currency detection and cash-equivalent handling consistent with one filter. Also raise when the positions response carries no results array, so a partial or schema-changed response leaves the previous snapshot in place instead of overwriting it with nothing. An empty results array remains a legitimately empty account. Note that tax_lots[].cost_basis is documented as a whole-lot total, unlike the per-share field this reads. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>