コード例 #1
0
def balance_check(entries, options_map):
    errors = []
    tracking_accounts = set()
    for entry in entries:
        if isinstance(entry, Open):
            if entry.meta.get('tracking', False):
                tracking_accounts.add(entry.account)
    asum = Inventory()
    bsum = Inventory()
    for entry in filter_txns(entries):
        for posting in entry.postings:
            if posting.account in tracking_accounts:
                continue
            components = posting.account.split(':')
            if components[0] in ('Assets', 'Liabilities'):
                asum.add_position(posting)
            elif components[0] in ('Income', 'Expenses'):
                bsum.add_position(posting)
    csum = asum.reduce(convert.get_weight) + bsum.reduce(convert.get_weight)
    if not csum.is_small(interpolate.infer_tolerances({}, options_map)):
        errors.append(
            BudgetBalanceError(
                {
                    'filename': '<budget_balance_check>',
                    'lineno': 0
                },
                f"On-budget accounts and budget total do not match: {asum} vs {-bsum}",
                None))
    return entries, errors
コード例 #2
0
    def test_units1(self):
        inv = Inventory()
        self.assertEqual(inv.reduce(convert.get_units), I(''))

        inv = I('40.50 JPY, 40.51 USD {1.01 CAD}, 40.52 CAD')
        self.assertEqual(inv.reduce(convert.get_units),
                         I('40.50 JPY, 40.51 USD, 40.52 CAD'))

        # Check that the same units coalesce.
        inv = I('2 HOOL {400 USD}, 3 HOOL {410 USD}')
        self.assertEqual(inv.reduce(convert.get_units), I('5 HOOL'))

        inv = I('2 HOOL {400 USD}, -3 HOOL {410 USD}')
        self.assertEqual(inv.reduce(convert.get_units), I('-1 HOOL'))
コード例 #3
0
def compute_portfolio_values(
        price_map: prices.PriceMap,
        transactions: data.Entries) -> Tuple[List[Date], List[float]]:
    """Compute a serie of portfolio values over time."""

    # Infer the list of required prices.
    currency_pairs = set()
    for entry in transactions:
        for posting in entry.postings:
            if posting.meta["category"] is Cat.ASSET:
                if posting.cost:
                    currency_pairs.add(
                        (posting.units.currency, posting.cost.currency))

    first = lambda x: x[0]
    price_dates = sorted(itertools.chain(
        ((date, None) for pair in currency_pairs
         for date, _ in prices.get_all_prices(price_map, pair)),
        ((entry.date, entry) for entry in transactions)),
                         key=first)

    # Iterate computing the balance.
    value_dates = []
    value_values = []
    balance = Inventory()
    for date, group in itertools.groupby(price_dates, key=first):
        # Update balances.
        for _, entry in group:
            if entry is None:
                continue
            for posting in entry.postings:
                if posting.meta["category"] is Cat.ASSET:
                    balance.add_position(posting)

        # Convert to market value.
        value_balance = balance.reduce(convert.get_value, price_map, date)
        cost_balance = value_balance.reduce(convert.convert_position, "USD",
                                            price_map)
        pos = cost_balance.get_only_position()
        value = pos.units.number if pos else ZERO

        # Add one data point.
        value_dates.append(date)
        value_values.append(value)

    return value_dates, value_values
コード例 #4
0
ファイル: charts.py プロジェクト: mhansen/fava
    def net_worth(self, interval):
        """Compute net worth.

        Args:
            interval: A string for the interval.

        Returns:
            A list of dicts for all ends of the given interval containing the
            net worth (Assets + Liabilities) separately converted to all
            operating currencies.
        """
        transactions = (entry for entry in self.ledger.entries
                        if (isinstance(entry, Transaction)
                            and entry.flag != flags.FLAG_UNREALIZED))

        types = (self.ledger.options['name_assets'],
                 self.ledger.options['name_liabilities'])

        txn = next(transactions, None)
        inventory = Inventory()

        for date in self.ledger.interval_ends(interval):
            while txn and txn.date < date:
                for posting in filter(lambda p: p.account.startswith(types),
                                      txn.postings):
                    inventory.add_position(posting)
                txn = next(transactions, None)
            yield {
                'date': date,
                'balance': {
                    currency:
                    inventory.reduce(convert.convert_position, currency,
                                     self.ledger.price_map,
                                     date).get_currency_units(currency).number
                    for currency in self.ledger.options['operating_currency']
                }
            }
コード例 #5
0
 def test_cost(self):
     inv = Inventory(self.POSITIONS_ALL_KINDS +
                     [P('50.00 CAD')])
     inv_cost = inv.reduce(convert.get_cost)
     self.assertEqual(I('40.50 USD, 139.10 CAD'), inv_cost)
コード例 #6
0
 def test_units(self):
     inv = Inventory(self.POSITIONS_ALL_KINDS +
                     [P('50.00 CAD')])
     inv_cost = inv.reduce(convert.get_units)
     self.assertEqual(I('121.50 USD, 50.00 CAD'), inv_cost)
コード例 #7
0
        new_inventory = Inventory()
        do_round = True
        for position in inventory:
            # units_digits = get_digits(position.units.number)
            # cost_digits = get_digits(position.cost.number)
            units_digits = 4
            cost_digits = 4
            new_units_number = position.units.number * new_to_old_ratio
            new_cost_number = position.cost.number / new_to_old_ratio
            if do_round:
                new_units_number = round(new_units_number, units_digits)
                new_cost_number = round(new_cost_number, cost_digits)
            new_position = Position(units=Amount(new_units_number,
                                                 new_currency),
                                    cost=Cost(number=new_cost_number,
                                              currency=position.cost.currency,
                                              date=position.cost.date,
                                              label=position.cost.label))
            new_inventory.add_position(new_position)
            print('  %s %s' % (args.transfer_to, new_position))
            print('  %s %s' % (args.account, -position))
        print('New units: ', new_inventory.reduce(get_units))
        print('New cost: ', new_inventory.reduce(get_cost))
    elif args.transfer_to:
        for position in inventory:
            print('  %s %s' % (args.transfer_to, position))
            print('  %s %s' % (args.account, -position))
    else:
        for position in inventory:
            print('  %s %s' % (args.account, position))
コード例 #8
0
ファイル: __init__.py プロジェクト: scauligi/refried
 def _row_children(self, rows, a):
     sum = Inventory()
     for sub in rows:
         if sub.startswith(a.account):
             sum.add_inventory(rows.get(sub, Inventory()))
     return -self._only_position(sum.reduce(convert.get_weight))