73 lines
2.4 KiB
Python
Executable File
73 lines
2.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
from beancount import loader
|
|
from beancount.query import query
|
|
from beancount.parser import printer
|
|
import argparse
|
|
from tabulate import tabulate
|
|
from decimal import Decimal
|
|
from beancount.core.amount import Amount, sub, mul, add
|
|
from math import floor
|
|
|
|
class bcolors:
|
|
HEADER = '\033[95m'
|
|
OKBLUE = '\033[94m'
|
|
OKCYAN = '\033[96m'
|
|
OKGREEN = '\033[92m'
|
|
WARNING = '\033[93m'
|
|
FAIL = '\033[91m'
|
|
ENDC = '\033[0m'
|
|
BOLD = '\033[1m'
|
|
UNDERLINE = '\033[4m'
|
|
|
|
def draw_line():
|
|
print('─' * 30)
|
|
|
|
def print_report(date, positions):
|
|
print(f"{bcolors.BOLD}Portfolio (date={date}){bcolors.ENDC}")
|
|
draw_line()
|
|
print(f"{bcolors.BOLD}Positions{bcolors.ENDC}")
|
|
print(tabulate(map(lambda p: [
|
|
p.account,
|
|
p.volume.average().get_only_position().units.number.__round__(2),
|
|
f"{p.volume.average().get_only_position().cost.number.__round__(2)} {p.volume.average().get_only_position().cost.currency}",
|
|
f"{p.position.get_only_position().units.number.__round__(2)} {p.position.get_only_position().units.currency}"], positions)
|
|
, headers=["Actiu", "Quantitat", "Últim preu", "Valor"]))
|
|
total = Amount(Decimal(0), 'EUR')
|
|
for p in positions:
|
|
total = add(total, p.position.get_only_position().units)
|
|
print(tabulate([
|
|
["Total", "", "", f"{total.number.__round__(2)} {total.currency}"]
|
|
]))
|
|
print(f"{bcolors.BOLD}Plusvalias / Minusvalias{bcolors.ENDC}")
|
|
print(f"{bcolors.BOLD}Distribució geografica / sectors{bcolors.ENDC}")
|
|
print(f"{bcolors.BOLD}Indicadors{bcolors.ENDC}")
|
|
print(tabulate([
|
|
["Alfa", 1],
|
|
["Beta", 1]
|
|
]))
|
|
|
|
|
|
def get_positions(entries, options, date):
|
|
balance_query = f"SELECT account, sum(position) as volume, convert(sum(position), \"EUR\") as position FROM date <= {date} WHERE account ~ '^Assets:Invest' GROUP BY account"
|
|
rtypes, rrows = query.run_query(
|
|
entries, options, balance_query)
|
|
return rrows
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description='Generate portfolio report')
|
|
parser.add_argument('date', metavar='date', type=str, nargs=1,
|
|
help='Report date in ISO format (e.g. 1970-01-01)')
|
|
|
|
args = parser.parse_args()
|
|
date = args.date[0]
|
|
|
|
filename = "ledger/main.beancount"
|
|
entries, errors, options = loader.load_file(filename)
|
|
|
|
if errors:
|
|
printer.print_errors(errors)
|
|
|
|
positions = get_positions(entries, options, date)
|
|
print_report(date, positions)
|
|
|
|
main() |