27 abril 2024
This commit is contained in:
73
commands/portfolio
Executable file
73
commands/portfolio
Executable file
@@ -0,0 +1,73 @@
|
||||
#!/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()
|
||||
Reference in New Issue
Block a user