Exemple #1
0
def test_filter():
    t = table.Table(
        ['units', 'currency'], [D, str],
        [[D('0.01'), 'USD'], [D('0.02'), 'CAD'], [D('0.03'), 'AUD']])
    nt = t.filter(lambda row: row.currency == 'USD')
    assert nt.columns == t.columns
    assert nt.types == t.types
    assert nt.rows == list(map(nt.Row._make, [[D('0.01'), 'USD']]))
Exemple #2
0
def test_select():
    t = table.Table(
        ['units', 'currency'], [D, str],
        [[D('0.01'), 'USD'], [D('0.02'), 'CAD'], [D('0.03'), 'AUD']])
    nt = t.select(['currency'])
    assert nt.columns == ['currency']
    assert nt.types == [str]
    assert nt.rows == list(map(nt.Row, ['USD', 'CAD', 'AUD']))
Exemple #3
0
def test_constructor():
    t = table.Table(
        ['units', 'currency'], [D, str],
        [[D('0.01'), 'USD'], [D('0.02'), 'CAD'], [D('0.03'), 'AUD']])
    assert isinstance(t, table.Table)
    assert isinstance(t.Row, type)
    assert issubclass(t.Row, tuple)
    assert isinstance(t.rows, list)
    assert isinstance(t.rows[0], t.Row)
Exemple #4
0
def test_update():
    t = table.Table(
        ['units', 'currency'], [D, str],
        [[D('0.01'), 'USD'], [D('0.02'), 'CAD'], [D('0.03'), 'AUD']])
    nt = t.update('currency', lambda row: row.currency.lower())
    assert nt.columns == ['units', 'currency']
    assert nt.types == [D, str]
    assert nt.rows == list(
        map(nt.Row._make,
            [[D('0.01'), 'usd'], [D('0.02'), 'cad'], [D('0.03'), 'aud']]))
Exemple #5
0
def parse(filename: str) -> table.Table:
    """Parse the NASDAQ ETFs list."""
    tbl = table.read_csv(filename)
    outrows = []
    for row in tbl:
        for regexp, issuer in [('Vanguard', 'Vanguard'),
                               ('iShares', 'iShares'),
                               ('PowerShares', 'PowerShares'),
                               ('StateStreet', 'StateStreet')]:
            if re.search(regexp, row.name):
                outrows.append((row.symbol, issuer, row.name))
                break

    return table.Table(['ticker', 'issuer', 'name'], [str, str, str], outrows)
Exemple #6
0
def test_read_csv():
    buf = io.StringIO(
        textwrap.dedent("""
      units,currency
      0.01,USD
      0.02,CAD
      0.03,AUD
    """))
    t = table.read_csv(buf)
    e = table.Table(['units', 'currency'], [str, str],
                    [[('0.01'), 'USD'], [('0.02'), 'CAD'], [('0.03'), 'AUD']])
    assert t.columns == e.columns
    assert t.types == e.types
    assert t.rows == e.rows
Exemple #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 filename')
    parser.add_argument('--currency', action='store', default='USD')
    parser.add_argument('--quantize', action='store', default='0.')
    parser.add_argument('-o', '--output', action='store', help="Output file")
    args = parser.parse_args()
    Q = Decimal(args.quantize)

    # Read input.
    entries, errors, options_map = loader.load_file(args.filename)
    price_map = prices.build_price_map(entries)
    acctypes = options.get_account_types(options_map)

    # Compute start of period.
    today = datetime.date.today()
    date_min = today - datetime.timedelta(days=2 * 365)
    date_start = datetime.date(date_min.year, date_min.month, 1)
    month_start = (date_min.year, date_min.month)

    # Compute end of period.
    date_max = datetime.date(today.year, today.month, 1)

    # Accumulate expenses for the period.
    balances = collections.defaultdict(
        lambda: collections.defaultdict(inventory.Inventory))
    all_months = set()
    for entry in data.filter_txns(entries):
        if entry.date < date_start or entry.date >= date_max:
            continue
        if any(tag.startswith(EXCLUDE_TAG_PREFIX) for tag in entry.tags):
            continue
        month = (entry.date.year, entry.date.month)
        all_months.add(month)
        for posting in entry.postings:
            if account_types.get_account_type(
                    posting.account) != acctypes.expenses:
                continue
            if any(regexp.match(posting.account) for regexp in EXCLUDES):
                continue
            if posting.units.currency != args.currency:
                continue
            account = posting.account
            for regexp, target_account in MAPS:
                if regexp.match(account):
                    account = target_account
                    break
            balances[account][month].add_position(posting)

    # Reduce the final balances to numbers.
    sbalances = collections.defaultdict(dict)
    for account, months in sorted(balances.items()):
        for month, balance in sorted(months.items()):
            year, mth = month
            date = datetime.date(year, mth, 1)
            balance = balance.reduce(convert.get_value, price_map, date)
            balance = balance.reduce(convert.convert_position, args.currency,
                                     price_map, date)
            try:
                pos = balance.get_only_position()
            except AssertionError:
                print(balance)
                raise
            total = pos.units.number if pos and pos.units else None
            sbalances[account][month] = total

    # Pivot the table.
    header_months = sorted(all_months)
    header = ['account'] + ['{}-{:02d}'.format(*m) for m in header_months]
    rows = []
    for account in sorted(sbalances.keys()):
        row = [account]
        for month in header_months:
            total = sbalances[account].get(month, None)
            row.append(str(total.quantize(Q)) if total else '')
        rows.append(row)

    # Write out the table.
    tbl = table.Table(header, [str] + [Decimal] * (len(header) - 1), rows)
    if args.output:
        with open(args.output, 'w') as outfile:
            table.write_csv(tbl, outfile)
    print(tbl)
Exemple #8
0
def AssetsTable(rows):
    """A table describing the list of assets."""
    return table.Table(['ticker', 'issuer', 'quantity'], [str, str, float],
                       rows)