Ejemplo n.º 1
0
def classify_holdings_for_export(holdings_list, commodities_map):
    """Figure out what to do for example with each holding.

    Args:
      holdings_list: A list of Holding instances to be exported.
      commodities_map: A dict of commodity to Commodity instances.
    Returns:
      A pair of:
        action_holdings: A list of (symbol, holding) for each holding. 'Symbol'
          is the ticker to use for export, and may be "CASH" or "IGNORE" for
          holdings to be converted or ignored.
    """
    # Get the map of commodities to tickers and export meta tags.
    exports = getters.get_values_meta(commodities_map, FIELD)

    # Classify the holdings based on their commodities' ticker metadata field.
    action_holdings = []
    for holding in holdings_list:
        # Get export field and remove (MONEY:...) specifications.
        export = re.sub(r'\(.*\)', '', exports.get(holding.currency, None) or '').strip()
        if export:
            if export.upper() == "CASH":
                action_holdings.append(('CASH', holding))
            elif export.upper() == "IGNORE":
                action_holdings.append(('IGNORE', holding))
            else:
                action_holdings.append((export, holding))
        else:
            logging.warning(("Exporting holding using default commodity name '{}'; this "
                             "can potentially break the OFX import. Consider providing "
                             "'export' metadata for your commodities.").format(
                                 holding.currency))
            action_holdings.append((holding.currency, holding))

    return action_holdings
Ejemplo n.º 2
0
def main():
    import argparse, logging
    logging.basicConfig(level=logging.INFO,
                        format='%(levelname)-8s: %(message)s')
    parser = argparse.ArgumentParser(description=__doc__.strip())
    parser.add_argument('filename', help='Filename')
    args = parser.parse_args()

    entries, errors, options_map = loader.load_file(args.filename)

    commodity_map = getters.get_commodity_map(entries, options_map)
    ticker_info = getters.get_values_meta(commodity_map, 'name', 'ticker',
                                          'quote')

    print('Fetching:')
    for currency, (name, ticker, cost_currency) in sorted(ticker_info.items()):
        if ticker:
            print('{:16} {:16} {:16} {}'.format(currency, ticker,
                                                cost_currency, name))
    print()

    print('Skipping:')
    for currency, (name, ticker, cost_currency) in sorted(ticker_info.items()):
        if not ticker:
            print('{:16} {:16} {:16} {}'.format(currency, '', cost_currency
                                                or '', name or ''))
Ejemplo n.º 3
0
def classify_holdings_for_export(holdings_list, commodities_map):
    """Figure out what to do for example with each holding.

    Args:
      holdings_list: A list of Holding instances to be exported.
      commodities_map: A dict of commodity to Commodity instances.
    Returns:
      A pair of:
        action_holdings: A list of (symbol, holding) for each holding. 'Symbol'
          is the ticker to use for export, and may be "CASH" or "IGNORE" for
          holdings to be converted or ignored.
    """
    # Get the map of commodities to tickers and export meta tags.
    tickers = getters.get_values_meta(commodities_map, 'ticker')
    exports = getters.get_values_meta(commodities_map, 'export')

    # Classify the holdings based on their commodities' ticker metadata field.
    action_holdings = []
    for holding in holdings_list:
        export = exports.get(holding.currency, None)
        ticker = tickers.get(holding.currency, None)
        if isinstance(export, str) and export:
            if export.upper() == "CASH":
                action_holdings.append(('CASH', holding))
            elif export.upper() == "IGNORE":
                action_holdings.append(('IGNORE', holding))
            elif export.upper() == "MONEY":
                # Hmm this is an interesting case... an actual holding is in
                # units of our money-market standing. We could disallow this,
                # but we can also just export it. Let's export it with the
                # ticker value or commodity if present.
                action_holdings.append(
                    (ticker if ticker else holding.currency, holding))
            else:
                action_holdings.append((export, holding))
        elif ticker:
            action_holdings.append((ticker, holding))
        else:
            logging.warn(
                ("Exporting holding using default commodity name '{}'; this "
                 "can potentially break the OFX import. Consider providing "
                 "'ticker' or 'export' metadata for your commodities.").format(
                     holding.currency))
            action_holdings.append((holding.currency, holding))

    return action_holdings
Ejemplo n.º 4
0
 def test_get_values_meta__multi(self):
     entries, _, options_map = loader.load_string(TEST_INPUT)
     commodity_map = getters.get_commodity_map(entries, options_map)
     values = getters.get_values_meta(commodity_map, 'name', 'ticker')
     self.assertEqual({'HOOL': ('Hooli Corp.', 'NYSE:HOOLI'),
                       'PIPA': ('Pied Piper', None),
                       'USD': (None, None)},
                      values)
Ejemplo n.º 5
0
 def test_get_values_meta__single(self):
     entries, _, options_map = loader.load_string(TEST_INPUT)
     commodity_map = getters.get_commodity_map(entries, options_map)
     values = getters.get_values_meta(commodity_map, 'name', default='BLA')
     self.assertEqual({'USD': 'BLA',
                       'PIPA': 'Pied Piper',
                       'HOOL': 'Hooli Corp.'},
                      values)
Ejemplo n.º 6
0
    def generate_table(self, entries, errors, options_map):
        commodity_map = getters.get_commodity_map(entries, options_map)
        ticker_info = getters.get_values_meta(commodity_map, 'name', 'ticker', 'quote')

        price_rows = [
            (currency, cost_currency, ticker, name)
            for currency, (name, ticker, cost_currency) in sorted(ticker_info.items())
            if ticker]

        return table.create_table(price_rows,
                                  [(0, "Currency"),
                                   (1, "Cost-Currency"),
                                   (2, "Symbol"),
                                   (3, "Name")])
Ejemplo n.º 7
0
def main():
    logging.basicConfig(level=logging.INFO, format='%(levelname)-8s: %(message)s')
    parser = argparse.ArgumentParser(description=__doc__.strip())
    parser.add_argument('filename', help='Beancount input file')
    #parser.add_argument('docid', help="Spreadsheets doc id to update")
    parser.add_argument('-n', '--dry-run', action='store_true')
    args = parser.parse_args()

    # Load the file contents.
    entries, errors, options_map = loader.load_file(args.filename)

    # Enumerate the list of assets.
    def keyfun(posting):
        if posting.cost is None:
            return (1, posting.units.currency, posting.account)
        else:
            return (0, posting.account, posting.cost.currency)

    postings = sorted(get_balance_sheet_balances(clean_entries_for_balances(entries),
                                                 options_map),
                      key=keyfun)

    # Simplify the accounts to their root accounts.
    root_accounts = get_root_accounts(postings)
    postings = [posting._replace(account=root_accounts[posting.account])
                for posting in postings]

    # Aggregate postings by account/currency.
    agg_postings = sorted(aggregate_postings(postings), key=keyfun)
    agg_postings = list(agg_postings)

    # Add prices to the postings.
    agg_postings = add_prices_to_postings(entries, agg_postings)

    # Get the map of commodities to export meta tags.
    commodities_map = getters.get_commodity_map(entries)
    exports = getters.get_values_meta(commodities_map, 'export')
    asset_type = getters.get_values_meta(commodities_map, 'assets')

    # Get the map of accounts to export meta tags.
    accounts_map = {
        account: open
        for account, (open, _) in getters.get_account_open_close(entries).items()}
    tax_map = populate_with_parents(getters.get_values_meta(accounts_map, 'tax'), 'TAXABLE')

    # Filter out postings to be ignored.
    agg_postings = [posting
                    for posting in agg_postings
                    if exports.get(posting.units.currency, None) != 'IGNORE']

    # Realize the model.
    price_map = prices.build_price_map(entries)
    model = Model(price_map, list(agg_postings), exports, asset_type, tax_map)

    # Write out the assets to stdout in CSV format.
    if args.dry_run:
        return
    table = model_to_table(model)
    table[0][0] += ' ({:%Y-%m-%d %H:%M})'.format(datetime.datetime.now())
    wr = csv.writer(sys.stdout)
    wr.writerows(table)