mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-08-07 22:45:20 +02:00
Investment Portfolio Sync (#974)
* Add investment portfolio models * Add portfolio to demo data * Setup initial tests * Rough sketch of sync logic * Clean up trade sync logic * Add trade validation * Integrate trades into sync process
This commit is contained in:
parent
d0bc959bee
commit
47523f64c2
32 changed files with 591 additions and 56 deletions
|
@ -27,13 +27,9 @@ class Account::Balance::Syncer
|
|||
attr_reader :sync_start_date, :account
|
||||
|
||||
def upsert_balances!(balances)
|
||||
current_time = Time.now
|
||||
balances_to_upsert = balances.map do |balance|
|
||||
{
|
||||
date: balance.date,
|
||||
balance: balance.balance,
|
||||
currency: balance.currency,
|
||||
updated_at: Time.now
|
||||
}
|
||||
balance.attributes.slice("date", "balance", "currency").merge("updated_at" => current_time)
|
||||
end
|
||||
|
||||
account.balances.upsert_all(balances_to_upsert, unique_by: %i[account_id date currency])
|
||||
|
@ -49,9 +45,9 @@ class Account::Balance::Syncer
|
|||
return valuation.amount if valuation
|
||||
return derived_sync_start_balance(entries) unless prior_balance
|
||||
|
||||
transactions = entries.select { |e| e.date == date && e.account_transaction? }
|
||||
entries = entries.select { |e| e.date == date }
|
||||
|
||||
prior_balance - net_transaction_flows(transactions)
|
||||
prior_balance - net_entry_flows(entries)
|
||||
end
|
||||
|
||||
def calculate_daily_balances
|
||||
|
@ -95,19 +91,19 @@ class Account::Balance::Syncer
|
|||
end
|
||||
|
||||
def derived_sync_start_balance(entries)
|
||||
transactions = entries.select { |e| e.account_transaction? && e.date > sync_start_date }
|
||||
transactions_and_trades = entries.reject { |e| e.account_valuation? }.select { |e| e.date > sync_start_date }
|
||||
|
||||
account.balance + net_transaction_flows(transactions)
|
||||
account.balance + net_entry_flows(transactions_and_trades)
|
||||
end
|
||||
|
||||
def find_prior_balance
|
||||
account.balances.where("date < ?", sync_start_date).order(date: :desc).first&.balance
|
||||
end
|
||||
|
||||
def net_transaction_flows(transactions, target_currency = account.currency)
|
||||
converted_transaction_amounts = transactions.map { |t| t.amount_money.exchange_to(target_currency, date: t.date) }
|
||||
def net_entry_flows(entries, target_currency = account.currency)
|
||||
converted_entry_amounts = entries.map { |t| t.amount_money.exchange_to(target_currency, date: t.date) }
|
||||
|
||||
flows = converted_transaction_amounts.sum(&:amount)
|
||||
flows = converted_entry_amounts.sum(&:amount)
|
||||
|
||||
account.liability? ? flows * -1 : flows
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue