From db1051d295935dadaaf651cdd1ea69e43fccaf1a Mon Sep 17 00:00:00 2001 From: Gian-Reto Tarnutzer Date: Sat, 9 May 2026 06:56:30 +0200 Subject: [PATCH] Fix: Use historical exchange rate for historical prices --- app/models/holding/portfolio_cache.rb | 2 +- test/models/holding/portfolio_cache_test.rb | 36 +++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/app/models/holding/portfolio_cache.rb b/app/models/holding/portfolio_cache.rb index ca6febe2e..4ea52920e 100644 --- a/app/models/holding/portfolio_cache.rb +++ b/app/models/holding/portfolio_cache.rb @@ -40,7 +40,7 @@ class Holding::PortfolioCache price_money = Money.new(price.price, price.currency) begin - converted_amount = price_money.exchange_to(account.currency).amount + converted_amount = price_money.exchange_to(account.currency, date: date).amount rescue Money::ConversionError converted_amount = price.price end diff --git a/test/models/holding/portfolio_cache_test.rb b/test/models/holding/portfolio_cache_test.rb index 4677fc411..fed652165 100644 --- a/test/models/holding/portfolio_cache_test.rb +++ b/test/models/holding/portfolio_cache_test.rb @@ -56,4 +56,40 @@ class Holding::PortfolioCacheTest < ActiveSupport::TestCase cache = Holding::PortfolioCache.new(@account, use_holdings: true) assert_equal holding.price, cache.get_price(@security.id, holding.date).price end + + test "converts historical prices using the requested date exchange rate" do + account = families(:empty).accounts.create!( + name: "CHF Brokerage", + balance: 10000, + currency: "CHF", + accountable: Investment.new + ) + holding_date = 2.days.ago.to_date + + ExchangeRate.create!(from_currency: "USD", to_currency: "CHF", date: holding_date, rate: 0.80) + ExchangeRate.create!(from_currency: "USD", to_currency: "CHF", date: Date.current, rate: 0.95) + + Holding.create!( + security: @security, + account: account, + date: holding_date, + qty: 1, + price: 100, + amount: 100, + currency: "USD" + ) + + Security::Price.create!( + security: @security, + date: holding_date, + price: 100, + currency: "USD" + ) + + cache = Holding::PortfolioCache.new(account, use_holdings: true) + converted_price = cache.get_price(@security.id, holding_date) + + assert_equal BigDecimal("80.0"), converted_price.price + assert_equal "CHF", converted_price.currency + end end