From 027c18297b355600e32482f00a3e2fe28b212c93 Mon Sep 17 00:00:00 2001 From: Zach Gollwitzer Date: Thu, 12 Dec 2024 15:11:06 -0500 Subject: [PATCH] Fix holding avg cost calculation --- app/models/account/holding.rb | 8 ++++++-- app/views/shared/_money_field.html.erb | 1 - test/models/account/holding_test.rb | 9 +++++++++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/app/models/account/holding.rb b/app/models/account/holding.rb index d5f3e01457c..bd2e1ca32c6 100644 --- a/app/models/account/holding.rb +++ b/app/models/account/holding.rb @@ -26,8 +26,12 @@ def weight # Basic approximation of cost-basis def avg_cost - avg_cost = account.holdings.for(security).where(currency: currency).where("date <= ?", date).average(:price) - Money.new(avg_cost, currency) + avg_cost = account.entries.account_trades + .joins("INNER JOIN account_trades ON account_trades.id = account_entries.entryable_id") + .where("account_trades.security_id = ? AND account_trades.qty > 0 AND account_entries.date <= ?", security.id, date) + .average(:price) + + Money.new(avg_cost || price, currency) end def trend diff --git a/app/views/shared/_money_field.html.erb b/app/views/shared/_money_field.html.erb index 4a3f80011cf..a2db645c91f 100644 --- a/app/views/shared/_money_field.html.erb +++ b/app/views/shared/_money_field.html.erb @@ -36,7 +36,6 @@ step: currency.step, data: { "money-field-target": "amount", - action: "change->money-field#handleAmountChange", "auto-submit-form-target": ("auto" if options[:auto_submit]) }.compact, required: options[:required] %> diff --git a/test/models/account/holding_test.rb b/test/models/account/holding_test.rb index dc521801009..c3bf1c39a9d 100644 --- a/test/models/account/holding_test.rb +++ b/test/models/account/holding_test.rb @@ -20,11 +20,20 @@ class Account::HoldingTest < ActiveSupport::TestCase end test "calculates simple average cost basis" do + create_trade(@amzn.security, account: @account, qty: 10, price: 212.00, date: 1.day.ago.to_date) + create_trade(@amzn.security, account: @account, qty: 15, price: 216.00, date: Date.current) + + create_trade(@nvda.security, account: @account, qty: 5, price: 128.00, date: 1.day.ago.to_date) + create_trade(@nvda.security, account: @account, qty: 30, price: 124.00, date: Date.current) + assert_equal Money.new((212.0 + 216.0) / 2), @amzn.avg_cost assert_equal Money.new((128.0 + 124.0) / 2), @nvda.avg_cost end test "calculates total return trend" do + @amzn.stubs(:avg_cost).returns(Money.new(214.00)) + @nvda.stubs(:avg_cost).returns(Money.new(126.00)) + # Gained $30, or 0.93% assert_equal Money.new(30), @amzn.trend.value assert_in_delta 0.9, @amzn.trend.percent, 0.001