Feature: Recursive exchange rates #92

Open
opened 2025-12-28 23:26:00 +01:00 by adam · 1 comment
Owner

Originally created by @icovada on GitHub (Dec 28, 2025).

To track the value of a "Dollar Cost Average Tracker" I have set up three currencies:

  • the fund -> "F"
  • USD -> "$"
  • EUR -> €

I use Euro to buy shares in a fund, but to do so I have to first exchange EUR to dollars, so the exchange goes through two transactions.
If I set up the DCA to track "F x €" it shows all negatives because despite having that day's exchange rate for "FxUSD" and "USDxEUR" it doesn't have direct "FxEUR" exchanges.

We should be able to come up with that data anyway.

Originally created by @icovada on GitHub (Dec 28, 2025). To track the value of a "Dollar Cost Average Tracker" I have set up three currencies: - the fund -> "F" - USD -> "$" - EUR -> € I use Euro to buy shares in a fund, but to do so I have to first exchange EUR to dollars, so the exchange goes through two transactions. If I set up the DCA to track "F x €" it shows all negatives because despite having that day's exchange rate for "FxUSD" and "USDxEUR" it doesn't have direct "FxEUR" exchanges. We should be able to come up with that data anyway.
Author
Owner

@eitchtee commented on GitHub (Dec 28, 2025):

We have support for this using the Transitive Automatic Exchange Rate provider

519a85d256/app/apps/currencies/exchange_rates/providers.py (L91)

It does require explicit declaration of what currencies you want to calculate based on your existing exchange rates, but after it's configured:

It first fetches all existing exchange rates and builds a bidirectional graph where:

  • Each currency is a node.
  • Each edge represents a known exchange rate between two currencies.
  • Inverse rates are also added (e.g., if USD -> EUR exists, EUR -> USD is calculated as 1 / rate).

When you need a rate from currency A to currency B, it uses BFS to find the shortest path through the graph. For example: If you need EUR -> JPY but only have EUR -> USD and USD -> JPY, it will find the path EUR -> USD -> JPY.


Maybe we could modify get_exchange_rate()(here) to automatically fallback to the same behavior if it can't find a direct exchange rate, but I'm not sure this would perform well, considering we currently calculate everything at runtime (when it needs to be displayed to the user). The database cache we have should help a lot, just need to make sure the algorithm is good, as DCAs with a lot of entries already take some time to load due to this dynamic calculation, wouldn't want to slow it down even more.

@eitchtee commented on GitHub (Dec 28, 2025): We have support for this using the `Transitive` Automatic Exchange Rate provider https://github.com/eitchtee/WYGIWYH/blob/519a85d2566312797d7d70290f39cdc55e3fcb8d/app/apps/currencies/exchange_rates/providers.py#L91 It does require explicit declaration of what currencies you want to calculate based on your existing exchange rates, but after it's configured: It first fetches all existing exchange rates and builds a bidirectional graph where: - Each currency is a node. - Each edge represents a known exchange rate between two currencies. - Inverse rates are also added (e.g., if USD -> EUR exists, EUR -> USD is calculated as 1 / rate). When you need a rate from currency A to currency B, it uses BFS to find the shortest path through the graph. For example: If you need EUR -> JPY but only have EUR -> USD and USD -> JPY, it will find the path EUR -> USD -> JPY. --- Maybe we could modify `get_exchange_rate()`([here](https://github.com/eitchtee/WYGIWYH/blob/519a85d2566312797d7d70290f39cdc55e3fcb8d/app/apps/currencies/utils/convert.py)) to automatically fallback to the same behavior if it can't find a direct exchange rate, but I'm not sure this would perform well, considering we currently calculate everything at runtime (when it needs to be displayed to the user). The database cache we have should help a lot, just need to make sure the algorithm is good, as DCAs with a lot of entries already take some time to load due to this dynamic calculation, wouldn't want to slow it down even more.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/WYGIWYH#92