mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-08-07 06:25:19 +02:00
33 lines
1 KiB
Ruby
33 lines
1 KiB
Ruby
|
# Captures the most recent holding quantities for each security in an account's portfolio.
|
||
|
# Returns a portfolio hash compatible with the reverse calculator's format.
|
||
|
class Holding::PortfolioSnapshot
|
||
|
attr_reader :account
|
||
|
|
||
|
def initialize(account)
|
||
|
@account = account
|
||
|
end
|
||
|
|
||
|
# Returns a hash of {security_id => qty} representing today's starting portfolio.
|
||
|
# Includes all securities from trades (with 0 qty if no holdings exist).
|
||
|
def to_h
|
||
|
@portfolio ||= build_portfolio
|
||
|
end
|
||
|
|
||
|
private
|
||
|
def build_portfolio
|
||
|
# Start with all securities from trades initialized to 0
|
||
|
portfolio = account.trades
|
||
|
.pluck(:security_id)
|
||
|
.uniq
|
||
|
.each_with_object({}) { |security_id, hash| hash[security_id] = 0 }
|
||
|
|
||
|
# Get the most recent holding for each security and update quantities
|
||
|
account.holdings
|
||
|
.select("DISTINCT ON (security_id) security_id, qty")
|
||
|
.order(:security_id, date: :desc)
|
||
|
.each { |holding| portfolio[holding.security_id] = holding.qty }
|
||
|
|
||
|
portfolio
|
||
|
end
|
||
|
end
|