У меня есть PositionGroup
, что has_many :positions
.
При каждом прикосновении к объекту position_group
я бы хотел обновить pg.average_price
следующим образом:
# Average Price = ((position1.transaction_price * (position1.volume/total_volume) +
# position2.transaction_price * (position2.volume/total_volme))
In мой метод обратного вызова, я попробовал это:
def update_average_price
total_volume = positions.sum(:volume)
avg_price = positions.sum("transaction_price * (volume/#{total_volume})")
update_column(:average_price, avg_price)
end
Но когда я проверяю значение avg_price
после нескольких positions
существует, я получаю 0.0
.
Это мой spe c для этой специфической c функциональности:
it "should calculate the Weighted Average Purchase Price of all positions" do
# Position 3: Price = 20, volume = 200
# (Position 1 Price * (Position 1 Units/Total # of Units)) +
# (Position 2 Price * (Position 2 Units/Total # of Units)) +
# (Position 3 Price * (Position 3 Units/Total # of Units))
# ($10 * (100/400)) + ($15 * (100/400) + $20 * (100/400)) =
# ($2.50 + $3.75 + $5) = $11.25
price3 = 20
pos3 = create(:position, stock: stock, portfolio: portfolio, transaction_price: 20, current_price: price3, action: :buy, volume: 200, position_group: pg)
expect(pg.average_price).to eql 11.25
end
Это результат, когда я запускаю его:
1) PositionGroup methods should calculate the Weighted Average Purchase Price of all positions
Failure/Error: expect(pg.average_price).to eql 11.25
expected: 11.25
got: 0.0
(compared using eql?)
Я почти уверен, что проблема заключается в этой строке, из мой метод обратного вызова update_average_price
на PositionGroup
:
avg_price = positions.sum("transaction_price * (volume/#{total_volume})")
Есть ли лучший способ приблизиться к этому или есть что-то еще, дающее мне это 0.0
, когда меня не должно быть?