2025-04-14 11:40:34 -04:00
|
|
|
class Holding::ReverseCalculator < Holding::BaseCalculator
|
2025-03-07 17:35:55 -05:00
|
|
|
private
|
|
|
|
# Reverse calculators will use the existing holdings as a source of security ids and prices
|
|
|
|
# since it is common for a provider to supply "current day" holdings but not all the historical
|
|
|
|
# trades that make up those holdings.
|
|
|
|
def portfolio_cache
|
2025-04-14 11:40:34 -04:00
|
|
|
@portfolio_cache ||= Holding::PortfolioCache.new(account, use_holdings: true)
|
2025-03-07 17:35:55 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def calculate_holdings
|
|
|
|
current_portfolio = generate_starting_portfolio
|
|
|
|
previous_portfolio = {}
|
|
|
|
|
|
|
|
holdings = []
|
|
|
|
|
|
|
|
Date.current.downto(account.start_date).each do |date|
|
|
|
|
today_trades = portfolio_cache.get_trades(date: date)
|
|
|
|
previous_portfolio = transform_portfolio(current_portfolio, today_trades, direction: :reverse)
|
|
|
|
holdings += build_holdings(current_portfolio, date)
|
|
|
|
current_portfolio = previous_portfolio
|
|
|
|
end
|
|
|
|
|
|
|
|
holdings
|
|
|
|
end
|
|
|
|
|
|
|
|
# Since this is a reverse sync, we start with today's holdings
|
|
|
|
def generate_starting_portfolio
|
|
|
|
holding_quantities = empty_portfolio
|
|
|
|
|
|
|
|
todays_holdings = account.holdings.where(date: Date.current)
|
|
|
|
|
|
|
|
todays_holdings.each do |holding|
|
|
|
|
holding_quantities[holding.security_id] = holding.qty
|
|
|
|
end
|
|
|
|
|
|
|
|
holding_quantities
|
|
|
|
end
|
|
|
|
end
|