wealthfolio icon indicating copy to clipboard operation
wealthfolio copied to clipboard

[BUG] Portfolio performance not displayed when "multi-currency" activities are present

Open channel-42 opened this issue 5 months ago • 0 comments

Hey 👋🏻 First of all, thanks for building this awesome app 😊

While setting up my portfolio, I encountered 3 bugs. Two of them have relatively simple workarounds, while the third breaks the calculation and displaying of portfolio performance for me. I'll include the minor bugs at the end of this description, since I didn't want to flood the repo with issues.

Metadata

  • OS: macOS 15.5
  • App version: v1.1.6 (although the bug is also present when using dev build from main)
  • App currency: EUR
  • Account currency: EUR
  • Asset/Symbol currency: GBP, CHF

Description

My app's currency is in EUR. I also have my activities in EUR, as I buy via a German broker. Nevertheless, if the asset/symbol is listed in a different currency, e.g. VEVE.L is listed in GBP, the app fails to calculate the valuation, stating that no exchange rates were found for the time range the performance view is set to.

Looking into the DB, I can see that all the required exchange rates are present. After some digging, I narrowed it down to these sections:

  1. Empty fx_rates_today passed to https://github.com/afadil/wealthfolio/blob/4c0ad35474828458f65312d44c666890627f70cf/src-core/src/portfolio/valuation/valuation_calculator.rs#L28-L34 leading to valuation calculation for the given day being skipped.

  2. fx_rates_by_dateare fetched here https://github.com/afadil/wealthfolio/blob/4c0ad35474828458f65312d44c666890627f70cf/src-core/src/portfolio/valuation/valuation_service.rs#L216-L222 While start and end date are passed correctly, the required_fx_pairs is an empty set.

  3. required_fx_pairs is built here https://github.com/afadil/wealthfolio/blob/4c0ad35474828458f65312d44c666890627f70cf/src-core/src/portfolio/valuation/valuation_service.rs#L190-L207 This section only adds fx pairs if the position currency (activity currency) different from the account currency. Nevertheless, if the asset is listed in a different currency, we require this fx pair for later calculation of the rate. Since this pair does not get inserted, the calculation fails, with all data points being skipped and the performance graph showing a flat line.

Possible Fix

I'm not a rust dev and also not very familiar with your project's structure, so maybe my approach is lacking in some ways. Feel free to propose a better solution 🙂

I was able to fix this issue on my end by considering the asset's currency in the fx_pair insertion. I.e. I

  1. added the asset service to the valuation service
  2. fetched the asset by id
  3. compared the asset's currency to the the position currency to determine if the pair needs to be inserted
// in valuation_service.rs -> ValuestionSersice -> calculate_valuation_history(
for (asset_id, position) in &snapshot.positions {
  required_asset_ids.insert(asset_id.clone());
  // NOTE: Added this
  let asset = match self.assets_service.get_asset_by_id(asset_id) {
      Ok(asset) => asset,
      Err(e) => {
          warn!("Failed to get asset info for {}: {}. Using default currency.", asset_id, e);
          continue;
      }
  };

  if &position.currency != account_curr {
      required_fx_pairs.insert((position.currency.clone(), account_curr.clone()));
  }
  // log asset currency
  debug!(
      "Asset {} on {} has currency '{}'",
       asset_id, snapshot.snapshot_date, asset.currency
  );
  // NOTE: Added this
  if asset.currency !=  position.currency{
      debug!(
          "Asset {} on {} has different currency '{}' than position '{}'. Adding FX pair.",
          asset_id, snapshot.snapshot_date, asset.currency, position.currency
      );
      required_fx_pairs.insert((position.currency.clone(), asset.currency.clone()));
  }
}
// ...

I can open a PR if you'd like to share my fix and implement your feedback 👍🏻

Other Bugs

Open Me

FX rate not fetched when importing activities

When importing activities from CSV, FX rates are not fetched if symbols in the imported activities are in a different currency than the activity or the account. The current workaround is to manually add an activity for this symbol, which triggers the FX rate download.

Failure fetching info from fc.yahoo.com is silent and leads to wrong symbol info

When fetching info from fc.yahoo.com fails (in my case this was due to a DNS blocker like pihole), this failure is not communicated to the user. In my case, the fallback API did not return the symbol's currency, leading to the app assuming e.g. that VEVE.L was listed in EUR and calculating wrong performance.

I think it would help if we add a small error snackbar and allow the user to manually override the symbol's metadata (like the listing currency).

channel-42 avatar Jul 31 '25 09:07 channel-42