Commit Graph

6 Commits

Author SHA1 Message Date
CrossDrain
2cc9c80afa fix(holdings): carry provider cost_basis forward to calculated rows past snapshot date (#1818)
* fix(holdings): carry provider cost_basis forward to calculated rows

Providers like IBKR Flex emit holdings on report_date and only
include trades within the query window. The reverse calculator + gapfill therefore produces rows past report_date with nil cost_basis, even though the provider supplied a basis on the snapshot. That nil basis silently blanks `Trend`, the Reports "Total Return" card, the Top Holdings return column, and Gains by Tax Treatment, because every one of them gates on `holding.avg_cost`.

When a calculated row would otherwise have no usable cost_basis, backfill it with the most recent provider-supplied cost_basis for the same (security, currency) on or before the holding date. Existing calculated/manual values are preserved (they outrank a provider carry-forward), and existing provider carry-forwards are refreshed when a newer snapshot supersedes them.

* - Fix currency mismatch: provider snapshots were keyed by (security_id,
  currency) but calculated rows use account currency while IBKR provider
  rows use the security's native currency (e.g., USD vs EUR). Now keyed
  by security_id only; carry_forward_provider_cost_basis converts via
  Money#exchange_to at the snapshot date (same convention as
  ReverseCalculator for trade prices), with a ConversionError fallback.
- Trim long inline comment to three lines
- Fix safe-nav inconsistency: existing.cost_basis.positive? ->
  existing&.cost_basis&.positive?
- Add test: refreshes stale carry-forward when a newer provider snapshot
  arrives
- Add test: carry-forward is a no-op for forward-strategy accounts with
  no provider holdings

* fix(holdings): prevent overwriting zero-valued manual cost basis

Ensure that manual cost basis entries with a value of zero (e.g., for free
shares) are not overwritten by provider carry-forward values during
materialization.

Additionally, updated the logic to allow zero-valued manual or
calculated cost bases to be preserved, and added tests to verify
currency conversion and error handling during cost basis carry-forward.

* refactor(holdings): allow zero-valued cost basis in provider snapshots

Remove the filter that restricted provider cost basis snapshots to values
greater than zero. This ensures that manual cost basis entries with a
value of zero (e.g., for free shares) are correctly captured and
available for carry-forward logic.

* perf(holdings): optimize provider cost basis snapshot lookup

Filter provider cost basis snapshots by the security IDs present in the
current holdings set to reduce the amount of data loaded into memory.

* refactor(holdings): move PortfolioCache FX fix to dedicated branch

Remove date-accurate exchange rate fix from this branch — it has been
split into fix/portfolio-cache-historical-fx-rate to keep concerns
separate.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* revert(portfolio_cache): restore date-accurate FX in get_price

36676784 removed date: date from exchange_to intending to move it to
fix/portfolio-cache-historical-fx-rate, but that branch was a duplicate
of db1051d2 which was already in main. The revert therefore regressed
portfolio_cache.rb below main's state. Restore the historical exchange
rate lookup so this branch no longer removes a fix already present in main.

* fix(portfolio_cache): restore date-accurate FX and its test

36676784 removed date: date from exchange_to and deleted the historical
FX test, intending to carry them in fix/portfolio-cache-historical-fx-rate.
That branch was a duplicate of db1051d2 already in main, so the removal
regressed portfolio_cache.rb below main's state. Restore both.

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 23:33:48 +02:00
Gian-Reto Tarnutzer
ce5d7dd736 Add Interactive Brokers Provider (#1722)
* Display multi-currency holdings correctly

* Implement IBKR provider

* Fix: Use historical exchange rate for historical prices

* Add brokerage exchange rate for trades

* Sync historical balances from IBKR

* Add logos in activity history

* Fix privacy mode blur in account view

* Improve IBKR XML Flex report parser errors
2026-05-12 23:45:19 +02:00
Anas Limouri
a90f9b7317 Add CoinStats exchange portfolio sync and normalize linked investment charts (#1308)
* [FEATURE] Add CoinStats exchange portfolios and normalize linked investment charts

* [BUGFIX] Fix CoinStats PR regressions

* [BUGFIX] Fix CoinStats PR review findings

* [BUGFIX] Address follow-up CoinStats PR feedback

* [REFACTO] Extract CoinStats exchange account helpers

* [BUGFIX] Batch linked CoinStats chart normalization

* [BUGFIX] Fix CoinStats processor lint

---------

Signed-off-by: Juan José Mata <juanjo.mata@gmail.com>
Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
2026-04-01 20:25:06 +02:00
Ang Wei Feng (Ted)
b88734fb5e fix: allow refreshes from the same source for cost basis updates (#917)
* fix: allow refreshes from the same source for cost basis updates

* test: update cost basis priority expectations
2026-02-06 18:30:50 +01:00
LPW
fa78e1d292 Improve handling of cost_basis during holding materialization and display (#619)
- Refactored `persist_holdings` to separate and conditionally upsert holdings with and without cost_basis.
- Updated `avg_cost` logic to treat 0 cost_basis as unknown and return nil when cost_basis cannot be determined.
- Modified trend and investment calculation to exclude holdings with unknown cost_basis.
- Adjusted `average_cost` formatting to handle nil values in API responses and views.
- Added comprehensive tests to ensure cost_basis preservation and fallback behavior.
- Localized `unknown` label for display when cost_basis is unavailable.

Co-authored-by: Josh Waldrep <joshua.waldrep5+github@gmail.com>
2026-01-11 23:58:51 +01:00
Zach Gollwitzer
10f255a9a9 Clarify backend data pipeline naming concepts (importers, processors, materializers, calculators, and syncers) (#2255)
* Rename MarketDataSyncer to MarketDataImporter

* Materializers

* Importers

* More reference replacements
2025-05-17 16:37:16 -04:00