def get_value(self, pos, date): """Return the value and save the conversion rate.""" price_dates = [] price = convert.get_value(pos, self.price_map, date, price_dates) # Add prices found to the list of queried ones. for found_date, found_rate in price_dates: self.required_prices[(pos.units.currency, date)].add( (price.currency, found_date, found_rate)) return price
def read_assets(filename, currency, reduce_accounts, quantization): """Read a Beancount file and produce a list of assets. Args: filename: A string, the path to the Beancount file to read. currency: A string, the currency to convert all the contents to. reduce_accounts: A set of account names to be aggregated. quantization: A Decimal instance, to quantize all the resulting amounts. Returns: A list of (account-name, number-balance), numbers being assumed to be in the requested currency. """ # Read the Beancount input file. entries, _, options_map = loader.load_file(filename, log_errors=logging.error) acctypes = options.get_account_types(options_map) price_map = prices.build_price_map(entries) ocmap = getters.get_account_open_close(entries) # Compute aggregations. real_root = realization.realize(entries, compute_balance=True) # Reduce accounts which have been found in details (mutate the tree in-place). for account in reduce_accounts: real_acc = realization.get(real_root, account) real_acc.balance = realization.compute_balance(real_acc) real_acc.clear() # Prune all the closed accounts and their parents. real_root = prune_closed_accounts(real_root, ocmap) # Produce a list of accounts and their balances reduced to a single currency. acceptable_types = (acctypes.assets, acctypes.liabilities) accounts = [] for real_acc in realization.iter_children(real_root): atype = account_types.get_account_type(real_acc.account) if atype not in acceptable_types: continue try: _, close = ocmap[real_acc.account] if close is not None: continue except KeyError: #logging.info("Account not there: {}".format(real_acc.account)) if real_acc.account not in reduce_accounts and real_acc.balance.is_empty( ): continue value_inv = real_acc.balance.reduce( lambda x: convert.get_value(x, price_map)) currency_inv = value_inv.reduce(convert.convert_position, currency, price_map) amount = currency_inv.get_currency_units(currency) accounts.append( (real_acc.account, amount.number.quantize(quantization))) # Reduce this list of (account-name, balance-number) sorted by reverse amount order. accounts.sort(key=lambda x: x[1], reverse=True) return accounts
def position_value(context, pos, date=None): """Convert a position to its cost currency at the market value.""" return convert.get_value(pos, context.price_map, date)
def test_value__currency_from_price(self): pos = self._pos(A("100 HOOL"), None, A("520.00 USD")) self.assertEqual(A("53000.00 USD"), convert.get_value(pos, self.PRICE_MAP_HIT)) self.assertEqual(A("100 HOOL"), convert.get_value(pos, self.PRICE_MAP_EMPTY))
def test_value__currency_from_cost(self): pos = self._pos(A("100 HOOL"), Cost(D("514.00"), "USD", None, None)) self.assertEqual(A("53000.00 USD"), convert.get_value(pos, self.PRICE_MAP_HIT)) self.assertEqual(A("100 HOOL"), convert.get_value(pos, self.PRICE_MAP_EMPTY))
def test_value__no_currency(self): pos = self._pos(A("100 HOOL"), None) self.assertEqual(A("100 HOOL"), convert.get_value(pos, self.PRICE_MAP_EMPTY)) self.assertEqual(A("100 HOOL"), convert.get_value(pos, self.PRICE_MAP_HIT))
def __call__(self, context): args = self.eval_args(context) pos, date = args return convert.get_value(pos, context.price_map, date)
def __call__(self, context): args = self.eval_args(context) pos = args[0] return convert.get_value(pos, context.price_map, None)