Preskočiť na hlavný obsah

Ako Python skripty automatizujú Beancount a Fava

Beancount a Fava zostávajú skriptovateľné: používaj Python na automatizáciu reportov, bilancií a vlastných pracovných postupov vo vašej hlavnej knihe.

Beancount (jednoduchý nástroj na účtovníctvo s dvojstupňovým zápisom v plain-text formáte) a Fava (jeho webové rozhranie) sú vysoko rozšíriteľné a skriptovateľné. Ich dizajn vám umožňuje automatizovať finančné úlohy, generovať vlastné reporty a nastavovať upozornenia prostredníctvom písania Python skriptov. Slová jedného používateľa znejú: „Veľmi sa mi páči, že mám svoje dáta v takom pohodlnom formáte a tiež, že môžem automatizovať veci podľa svojej ľubovôle. Žiadne API nie je ako súbor na disku; je ľahké ho s čímkoľvek integrovať.“ Tento návod vás prevedie vytváraním skriptovateľných pracovných postupov – od jednoduchých automatizácií pre začiatočníkov až po pokročilé pluginy pre Favu.

Preskúmajte živý príklad hlavnej knihy:

Otvoriť Example Ledger v novej karte

Začnite s príkazovým riadkom bea

Predtým, než začnete písať akýkoľvek Python, skontrolujte, či už bea nesplní vašu úlohu. Overuje hlavnú knihu, vykonáva BQL dotazy, generuje štyri finančné reporty a importuje bankové exporty, a globálny --json z každého z nich vyrába parsovateľný obal, ktorý môže váš shell poslať do jq. Jeho návratové kódy sú zmluvou, na ktorej vychádza vetvenie plánovanej úlohy, takže cron alebo CI nepotrebujú žiadny loader skript. Viac informácií nájdete v automatizácii účtovníctva s bea, kde sú popísané ciele, obaly a vetvenie podľa návratových kódov, a vráťte sa sem, keď budete potrebovať vlastný výpočet, ktorý CLI neponúka.

Začíname: Spúšťanie Beancount ako Python skriptu

Pre nasledujúce vlastné Python skripty nainštalujte skriptovacie knižnice (pip install beancount beanquery beangulp). Pracovné postupy s príkazom bea namiesto toho používajú riadený engine; pre jeho inštaláciu postupujte podľa rýchleho návodu CLI. Keďže Beancount je napísaný v Pythone, môžete ho používať ako knižnicu vo vlastných skriptoch. Skripty nižšie boli spustené s Beancount 3.2.3, beanquery 0.2.0 a beangulp 0.2.0. Všeobecný prístup je:

  • Načítajte vašu Beancount hlavnú knihu: Použite Beancount loader na parsovanie súboru .beancount do Python objektov. Napríklad:

    from beancount import loader
    entries, errors, options = loader.load_file("myledger.beancount")
    if errors:
        for error in errors:
            print(error)
        raise SystemExit(1)

    Loader vracia záznamy a chyby spolu. Nevyvážený alebo neplatný súbor stále vráti záznamy, preto skontrolujte errors a zastavte sa pred tým, než začnete dáta dôverne používať. Všetky vaše účty, transakcie a zostatky sú teraz dostupné v kóde.

  • Využite Beancount Query Language (BQL): Namiesto manuálneho prechádzania môžete spúšťať SQL-podobné dotazy nad dátami. Dotazy sa nachádzajú v samostatnom balíku beanquery. Modul beancount.query v Beancount 3.2.3 neexistuje. Napríklad na získanie celkových výdavkov podľa mesiaca spojte načítané záznamy a vykonajte dotaz priamo:

    import beanquery
     
    conn = beanquery.connect("beancount:", entries=entries, errors=errors, options=options)
    cur = conn.execute(
        "SELECT year, month, sum(position) WHERE account ~ 'Expenses' GROUP BY year, month"
    )
    for row in cur.fetchall():
        print(row)

    Toto používa beanquery na agregáciu dát. Je to ten istý engine za bea query, ale tu ho voláte v skripte. Vyhnete sa tak spúšťaniu externého príkazu v slučke.

  • Nastavte štruktúru projektu: Organizujte svoje skripty spolu s hlavnou knihou. Bežné usporiadanie je mať adresáre pre importéry (na získavanie/analyzovanie externých dát), správy alebo dotazy (na analytické skripty) a dokumenty (na uchovávanie stiahnutých výpisov). Napríklad jeden používateľ má:

    • importers/ – vlastné Python importné skripty (s testami),
    • queries/ – skripty na generovanie správ (spustiteľné cez python3 queries/...),
    • documents/ – stiahnuté bankové CSV/PDF usporiadané podľa účtu.

S týmto nastavením môžete spúšťať skripty manuálne (napr. python3 queries/cash_flow.py) alebo ich plánovať (pomocou cron alebo spracovateľa úloh) na automatizáciu svojho pracovného postupu.

Automatizácia úloh zosúladenia

Zosúladenie znamená zabezpečiť, aby hlavná kniha zodpovedala externým záznamom (bankovým výpisom, kreditným kartám a pod.). Plain-text kniha Beancount a Python API umožňujú automatizovať veľkú časť tohto procesu.

Importovanie a párovanie transakcií (začiatočník)

Pre začiatočníkov je odporúčaný prístup používať importéry zo samostatného balíka beangulp. Beancount 3 odstránil modul v2 ingest a jeho príkaz extract. Napíšete malú Python triedu, ktorá dedí z beangulp.Importer na rozparsovanie daného formátu (CSV, OFX, PDF a pod.) a vygeneruje transakcie. Zaregistrujete ju v krátkom ingest skripte, potom ju spustíte cez bea ingest v spravovanom engine:

  • Napíšte importér (triedu v Pythone s metódami identify(), account() a extract()) pre CSV formát vašej banky.
  • Pridajte ingest skript, ktorý zaregistruje vaše importéry. bea ingest spúšťa príkazy identify, extract a archive zo skriptu. Napríklad jeden pracovný tok spustí extract na všetky súbory v ~/Downloads a výsledné transakcie zapíše do dočasného súboru.
  • Manuálne skontrolujte a skopírujte transakcie z dočasného súboru do vášho hlavného účtovného denníka, potom spustite bea check, aby ste zabezpečili zladenie salda.

Minimálny príklad: statement.csv so date,description,amount stĺpcami, ktorý parsuje tento importér (checking_importer.py):

import csv
import datetime
from beancount.core import data
from beancount.core.amount import Amount
from beancount.core.number import D
import beangulp
 
 
class CheckingImporter(beangulp.Importer):
    def identify(self, filepath: str) -> bool:
        return filepath.endswith("statement.csv")
 
    def account(self, filepath: str) -> str:
        return "Assets:Bank:Checking"
 
    def extract(self, filepath: str, existing):
        entries = []
        with open(filepath, newline="") as f:
            for row in csv.DictReader(f):
                date = datetime.date.fromisoformat(row["date"])
                amount = Amount(D(row["amount"]), "USD")
                meta = data.new_metadata(filepath, 0)
                entries.append(
                    data.Transaction(
                        meta, date, "*", None, row["description"],
                        data.EMPTY_SET, data.EMPTY_SET, [
                            data.Posting("Expenses:Food:Groceries", amount,
                                         None, None, None, None),
                            data.Posting("Assets:Bank:Checking",
                                         Amount(-amount.number, "USD"),
                                         None, None, None, None),
                        ]))
        return entries

Ingest skript (ingest.py) ho prepojí:

from checking_importer import CheckingImporter
from beangulp import Ingest
 
ingest = Ingest([CheckingImporter()])
 
if __name__ == "__main__":
    ingest()

Spustite ho na stiahnutom súbore. Pre lokálny CSV nie sú potrebné žiadne poverenia. Najprv nainštalujte systémovú knižnicu libmagic. Príkaz na jednorazové povolenie stiahne Beangulp do spravovaného enginu:

bea engine enable beangulp
bea ingest identify --config ingest.py statement.csv
bea ingest extract --config ingest.py statement.csv -o new.beancount

identify hlási checking_importer.CheckingImporter pre súbor. extract zapíše transakcie v Beancount formáte:

2024-01-08 * "Grocery Store"
  Expenses:Food:Groceries   120.00 USD
  Assets:Bank:Checking     -120.00 USD

Skontrolujte new.beancount, skopírujte zápisy do vášho hlavného denníka a spustite bea check.

Preskočte importér pre jednorazové použitie

Nemusíte písať importér na konverziu jedného výpisu. Vložte súbor do CSV to Beancount converter alebo použite OFX & QIF to Beancount pre .ofx, .qfx a .qif sťahovanie. Obidve bežia úplne vo vašom prehliadači, takže výpis nikdy neopustí váš počítač.

Hoci tento proces stále zahŕňa kontrolný krok, väčšina ťažkej práca s parsovaním a formátovaním zápisov je automatizovaná. Importérske skripty môžu tiež automaticky priraďovať kategórie a dokonca nastavovať balansové asercie (výpovede o očakávaných saldoch) na zachytenie nezrovnalostí. Napríklad po importe môžete mať riadok ako 2025-04-30 balance Assets:Bank:Checking 1234.56 USD, ktorý assertuje záverečné saldo. Keď spustíte bea check, Beancount skontroluje, či všetky tieto balansové asercie sú správne, a označí akékoľvek chyby, ak chýbajú alebo sú zdvojené transakcie. Toto je najlepšia prax: automaticky generovať balansové asercie pre každé obdobie výpisu, aby počítač pre vás odhalil nezreconciliované rozdiely.

Vlastné skripty pre zosúladenie (stredne pokročilé)

Pre väčšiu kontrolu môžete napísať vlastný Python skript, ktorý porovná zoznam transakcií banky (CSV alebo cez API) s vašimi zápismi v denníku:

  1. Prečítajte externé dáta: Parsujte CSV súbor banky pomocou modulu Pythonu csv (alebo Pandas). Normalizujte dáta do zoznamu transakcií, napr. každá so záznamom dátumu, sumy a popisu.
  2. Načítajte transakcie v účtovnej knihe: Použite loader.load_file, ako bolo ukázané skôr, aby ste získali všetky zápisy v účtovnej knihe. Filtrovať tento zoznam na zaujímavý účet (napr. váš bežný účet) a prípadne časové obdobie výpisu.
  3. Porovnajte a nájdite nezrovnalosti:
  • Pre každú externú transakciu skontrolujte, či existuje identický zápis v účtovnej knihe (zhoda podľa dátumu a sumy, možno aj popisu). Ak sa nenájde, označte ju ako „novú“ a prípadne ju vyexportujte ako transakciu vo formáte Beancount, aby ste ju mohli skontrolovať.
  • Naopak, identifikujte všetky zápisy v účtovnej knihe na danom účte, ktoré sa v externom zdroji nevyskytujú – môžu to byť chyby pri vklade dát alebo transakcie, ktoré ešte neboli v banke zúčtované.
  1. Výstup výsledkov: Vytlačte správu alebo vytvorte nový útržok .beancount s chýbajúcimi transakciami.

Ako príklad, komunitný skript nazvaný reconcile.py presne toto robí: vzhľadom na súbor Beancount a vstupné CSV vytlačí zoznam nových transakcií, ktoré by mali byť importované, ako aj existujúce účtovné zápisy, ktoré vo vstupnom súbore nie sú (čo môže byť znamením nesprávneho zaradenia). S takýmto skriptom môže byť mesačná kontrola jednoduchá ako jeho spustenie a následné doplnenie navrhovaných transakcií do účtovnej knihy. Jeden používateľ Beancount poznamenáva, že „robí proces zosúladenia pre všetky účty každý mesiac“ a používa rastúcu kolekciu Python kódu na elimináciu veľkej časti manuálnej práce pri importe a zosúladení dát.

Tip: Počas zosúladenia využite nástroje Beancount pre presnosť:

  • Použite asercie zostatku, ako bolo spomenuté, aby ste mali automatické kontroly zostatkov na účtoch.
  • Použite smernicu pad podľa želania, ktorá môže automaticky vložiť vyrovnávacie zápisy pre malé zaokrúhľovacie rozdiely (používajte opatrne).
  • Píšte jednotkové testy pre váš importér alebo logiku zosúladenia (Beancount poskytuje pomocné testy). Napríklad jeden workflow spočíval v tom, že sa vzal vzorový CSV, napísali sa neúspešné testy s očakávanými transakciami a potom sa implementoval importér, až pokým všetky testy neprešli. Toto zaručuje správnu funkčnosť importného skriptu pre rôzne prípady.

Generovanie vlastných správ a súhrnov

Zatiaľ čo Fava poskytuje mnoho štandardných správ (výkaz ziskov a strát, súvahu atď.), môžete vytvárať vlastné správy pomocou skriptov. Môžu to byť jednoduché výstupy do konzoly až po bohaté formátované súbory alebo grafy.

Získavanie údajov na vytváranie správ (začiatočník)

Na základnej úrovni môžete použiť Beancount Query Language (BQL) na získanie súhrnných údajov a ich vytlačenie alebo uloženie. Napríklad:

  • Súhrn peňažných tokov: Použite dotaz na vypočítanie čistého peňažného toku. „Peňažný tok“ môže byť definovaný ako zmena zostatku určitých účtov za obdobie. Pomocou BQL by ste mohli urobiť:

    SELECT year, month, sum(position)
    WHERE account ~ 'Income' OR account ~ 'Expenses'
    GROUP BY year, month

    Toto zrýchľuje všetky zápisy príjmov a výdavkov po mesiacoch. Filtrovať pomocou ~ a regulárneho výrazu: LIKE je syntaxová chyba v beanquery 0.2.0. Zápisy obsahujú position, nie amount. Každý riadok obsahuje jeden Inventory, takže každá mena je uvedená samostatne namiesto jej konverzie. Príjmy sú záporné a výdavky kladné. Môžete to spustiť cez bea query alebo cez Python API beanquery uvedené skôr a potom naformátovať výsledok.

  • Správa výdavkov podľa kategórie: Dotaz na celkové výdavky podľa kategórie:

    SELECT account, sum(position)
    WHERE account ~ 'Expenses'
    GROUP BY account
    ORDER BY sum(position) ASC

    Toto vytvára tabuľku výdavkov podľa kategórie. Každý súčet je Inventory v pôvodnej mene. Nezabalené agregáty do round(): neexistuje round(inventory, int) funkcia, takže round(sum(position), 2) zlyhá pri kompilácii. Môžete spustiť viacero dotazov v skripte a výstup môžete uložiť ako text, CSV alebo dokonca JSON na ďalšie spracovanie.

Jeden používateľ zistil, že je „triviálne“ analyzovať finančné údaje pomocou Fava alebo skriptov, pričom uviedol, že používajú jeden Python skript na získanie údajov z Beancount pomocou Query Language a následne vloženie do Pandas DataFrame na prípravu vlastnej správy. Napríklad môžete načítať mesačné sumy pomocou dotazu a potom použiť Pandas/Matplotlib na vykreslenie grafu peňažných tokov v priebehu času. Kombinácia BQL a knižníc na dátovú vedu vám umožňuje vytvárať správy presahujúce štandardné možnosti Favy.

Pokročilé správy (grafy, výkonnosť atď.)

Pre pokročilejšie potreby môžu vaše skripty počítať metriky, ako je výkonnosť investícií, alebo vytvárať vizuálne výstupy:

  • Výkonnosť investícií (IRR/XIRR): Keďže váš knihovník obsahuje všetky peňažné toky (nákupy, predaje, dividendy), môžete vypočítať výnosovosť portfólia. Napríklad môžete napísať skript, ktorý filtruje transakcie na vašich investičných účtoch a potom vypočíta vnútornú mieru návratnosti (IRR). Existujú knižnice (alebo vzorce) na výpočet IRR na základe údajov peňažných tokov. Niektoré rozšírenia Fava vyvinuté komunitou (ako PortfolioSummary alebo fava_investor) robia presne toto, vypočítavajú IRR a ďalšie metriky pre investičné portfóliá. Ako skript môžete použiť IRR funkciu (z NumPy alebo vlastnú) na sériu príspevkov/výberov plus konečnú hodnotu.

  • Viacperiódové alebo vlastné metriky: Chcete správu o vašej mierke úspor (pomer úspor k príjmu) za každý mesiac? Python skript môže načítať denník, sčítať všetky príjmové účty a všetky výdavkové účty, potom vypočítať úspory = príjmy - výdavky a percentuálny podiel. Toto môže vytvoriť peknú tabuľku alebo dokonca vygenerovať HTML/Markdown správu pre vaše záznamy.

  • Vizualizácia: Grafy môžete generovať mimo Fava. Napríklad použite matplotlib alebo altair v skripte na vytvorenie grafu čistého majetku v čase pomocou údajov z denníka. Pretože denník obsahuje všetky historické zostatky (alebo si ich môžete kumulovať prechodom položiek), môžete vytvárať časové rady. Tieto grafy uložte ako obrázky alebo interaktívny HTML. (Ak preferujete vizualizácie priamo v aplikácii, pozrite si časť o rozšíreniach Fava nižšie pre pridanie grafov vo vnútri Fava.)

Možnosti výstupu: Rozhodnite sa, ako doručiť správu:

  • Pre jednorazovú analýzu môže stačiť výpis na obrazovku alebo uloženie do CSV/Excel súboru.
  • Pre dashboardy zvážte generovanie HTML súboru s údajmi (možno pomocou šablónovacej knižnice ako Jinja2 alebo jednoducho zápis do Markdown), ktorý môžete otvoriť v prehliadači.
  • Môžete tiež integrovať s Jupyter Notebookmi pre interaktívne reportovanie, hoci to je skôr na prieskum než na automatizáciu.

Spúšťanie upozornení z vášho denníka

Ďalšie silné využitie skriptovateľných pracovných tokov je nastavenie upozornení založených na podmienkach vo vašich finančných údajoch. Pretože váš denník je pravidelne aktualizovaný (a môže obsahovať aj budúce položky, ako napríklad nadchádzajúce faktúry alebo rozpočty), skript ho môže prehľadávať a upozorniť vás na dôležité udalosti.

Varovania o nízkom zostatku na účte

Aby ste sa vyhli prečerpaniu alebo udržali minimálny zostatok, možno budete chcieť upozornenie, ak nejaký účet (napr. bežný alebo sporiaci) klesne pod určitý prah. Tu je, ako to môžete implementovať:

  1. Zistite aktuálne zostatky: Po načítaní entries pomocou loadera vypočítajte najnovší zostatok sledovaných účtov. Môžete to urobiť zrážaním zápisov alebo použitím dotazu. Napríklad použite BQL dotaz na zostatok konkrétneho účtu:

    SELECT sum(position) WHERE account = 'Assets:Bank:Checking'

    Toto vráti aktuálny zostatok daného účtu (súčet všetkých jeho zápisov). Prípadne použite interné funkcie Beancountu na tvorbu súvahy. Napríklad:

    from beancount.core import realization
    tree = realization.realize(entries)
    acct = realization.get_or_create(tree, "Assets:Bank:Checking")
    balance = acct.balance  # an Inventory of commodities

    Prejdite iba záznamy: druhý parameter je min_accounts, nie mapa možností. Potom extrahujte číselnú hodnotu (napr. balance.get_currency_units('USD') vráti desatinnú sumu v USD). Rovnako ako agregát dotazu, zostatok uchováva každú menu samostatne. Avšak použitie dotazu je pre väčšinu prípadov jednoduchšie.

  2. Skontrolujte prahovú hodnotu: Porovnajte zostatok s vaším preddefinovaným limitom. Ak je pod, spustite upozornenie.

  3. Spustite notifikáciu: Môže to byť jednoduché, ako vytlačiť varovanie do konzoly, ale pre skutočné upozornenia môžete poslať email alebo push notifikáciu. Môžete sa integrovať s emailom (cez smtplib) alebo so službou ako IFTTT či Slack webhook API na posielanie upozornení. Napríklad:

    if balance < 1000:
        send_email("Low balance alert", f"Account XYZ balance is {balance}")

    (Implementujte send_email s detailmi vášho emailového servera.)

Spustením tohto skriptu denne (prostredníctvom cron jobu alebo Windows Task Scheduler) dostanete proaktívne upozornenia. Keďže používa ledger, môže zohľadniť všetky transakcie vrátane tých, ktoré ste práve pridali.

Nadchádzajúce termíny platieb

Ak používate Beancount na sledovanie účtov alebo termínov, môžete označiť budúce platby a nechať si skriptami pripomínať. Dva spôsoby, ako v Beancount reprezentovať nadchádzajúce záväzky:

  • Udalosti: Beancount podporuje direktívu event pre ľubovoľné dátumové poznámky. Napríklad:

    2025-05-10 event "BillDue" "Mortgage payment due"

    Toto neovplyvňuje zostatky, ale zaznamenáva dátum s popisom. Skript môže skenovať entries pre záznamy Event, kde Event.type == "BillDue" (alebo akýkoľvek vlastný typ, ktorý si zvolíte) a skontrolovať, či je dátum v rámci napríklad nasledujúcich 7 dní od dneška. Ak áno, spustí upozornenie (email, notifikáciu alebo dokonca vyskakovacie okno).

  • Budúce transakcie: Niektorí ľudia zadávajú transakcie s budúcim dátumom (post-datované) pre veci ako plánované platby. Tieto sa nezobrazia v zostatkoch, kým neprejde dátum (ak nespravujete reporty podľa budúcich dátumov). Skript môže hľadať transakcie s dátumom v blízkej budúcnosti a vypísať ich.

Použitím týchto môžete vytvoriť skript „tickler“, ktorý pri spustení vygeneruje zoznam úloh alebo faktúr, ktoré čoskoro splatíte. Ak chcete, môžete ho integrovať s API ako Google Kalendár alebo správca úloh, aby sa tam automaticky vytvárali pripomienky.

Detekcia anomálií

Za známymi prahmi alebo dátumami môžete vytvárať skripty na vlastné upozornenia pre nezvyčajné vzory. Napríklad, ak bežný mesačný výdavok nenastal (možno ste zabudli zaplatiť faktúru), alebo ak sú výdavky v určitej kategórii tento mesiac abnormálne vysoké, váš skript by to mohol označiť. Zvyčajne to zahŕňa dotazovanie na nedávne údaje a porovnávanie s históriou (čo môže byť pokročilá téma – pravdepodobne využívajúca štatistiku alebo strojové učenie).

V praxi sa mnohí používatelia spoliehajú na zosúladenie na zachytenie anomálií (neočakávaných transakcií). Ak dostávate bankové upozornenia (napr. e-maily pre každú transakciu), môžete ich analyzovať skriptom a automaticky ich pridať do Beancount, alebo aspoň overiť, že sú zaznamenané. Jeden nadšenec dokonca nastavil svoju banku tak, aby posielala e-maily s upozorneniami na transakcie, s plánom ich automaticky analyzovať a doplniť do knihy. Tento druh udalostnými riadených upozornení môže zabezpečiť, že žiadna transakcia nezostane nezaznamenaná.

Rozšírenie Fava pomocou vlastných pluginov a zobrazení

Fava je už skriptovateľná cez svoj systém rozšírení. Ak chcete, aby sa vaša automatizácia alebo správy integrovali priamo do webového rozhrania, môžete napísať rozšírenie Fava (tiež nazývané plugin) v Pythone.

Ako fungujú rozšírenia Fava: Rozšírenie je Python modul, ktorý definuje triedu zdedenú z fava.ext.FavaExtensionBase. Zaregistrujete ho vo vašom Beancount súbore cez vlastnú možnosť. Napríklad, ak máte súbor myextension.py s triedou MyAlerts(FavaExtensionBase), môžete ho povoliť pridaním do vášho denníka:

1970-01-01 custom "fava-extension" "myextension"

Keď sa Fava načíta, importuje daný modul a inicializuje vašu triedu MyAlerts.

Rozšírenia môžu robiť niekoľko vecí:

  • Háčiky (Hooks): Môžu sa zavesiť na udalosti v životnom cykle Fava. Napríklad after_load_file() sa volá po načítaní ledgeru. Môžete to využiť na vykonanie kontrol alebo predvýpočet údajov. Ak by ste chceli implementovať kontrolu nízkeho zostatku vo vnútri Fava, after_load_file by mohol iterovať cez zostatky na účtoch a prípadne ukladať varovania (hoci ich zobrazenie v UI by mohlo vyžadovať trochu viac práce, ako napríklad vyvolanie FavaAPIError alebo použitie Javascriptu na zobrazenie notifikácie).
  • Vlastné reporty/stránky: Ak vaša trieda rozšírenia nastaví atribút report_title, Fava pridá novú stránku v bočnom paneli pre ňu. Potom poskytnete šablónu (HTML/Jinja2) pre obsah tejto stránky. Takto vytvoríte úplne nové pohľady, ako napríklad dashboard alebo súhrn, ktorý Fava v predvolenom nastavení nemá. Rozšírenie môže zhromaždiť akékoľvek potrebné dáta (môžete pristupovať k self.ledger, ktorý obsahuje všetky záznamy, zostatky atď.) a potom vyrenderovať šablónu.

Napríklad vstavané rozšírenie portfolio_list vo Fava pridáva stránku s výpisom vašich pozícií v portfóliu. Komunitné rozšírenia idú ešte ďalej:

  • Dashboardy: Plugin fava-dashboards umožňuje definovať vlastné grafy a panely (použitím knižníc ako Apache ECharts). Číta YAML konfiguračný súbor s dotazmi, vykoná ich cez Beancount a vygeneruje dynamickú dashboardovú stránku vo Fava. V podstate spája údaje z Beancount s JavaScriptovou knižnicou na vykresľovanie grafov a vytvára interaktívne vizualizácie.
  • Analýza portfólia: Rozšírenie PortfolioSummary (užívateľsky prispievané) počíta investičné súhrny (zoskupovanie účtov, výpočet IRR atď.) a zobrazuje ich v UI Fava.
  • Prehľad transakcií: Ďalšie rozšírenie, fava-review, pomáha s prehľadávaním transakcií v čase (napríklad aby ste nestratili žiadne doklady).

Ak chcete vytvoriť jednoduché rozšírenie sami, začnite podtriedou FavaExtensionBase. Napríklad minimálne rozšírenie, ktoré pridá stránku, môže vyzerať takto:

from fava.ext import FavaExtensionBase
 
class HelloReport(FavaExtensionBase):
    report_title = "Hello World"
 
    def __init__(self, ledger, config):
        super().__init__(ledger, config)
        # any initialization, perhaps parse config if provided
 
    def after_load_file(self):
        # (optional) run after ledger is loaded
        print("Ledger loaded with", len(self.ledger.entries), "entries")

Ak by ste toto umiestnili do hello.py a pridali custom "fava-extension" "hello" do vášho ledgeru, Fava by zobrazila novú stránku "Hello World" (tiež by ste potrebovali template súbor HelloReport.html v podadresári templates, aby ste definovali obsah stránky, pokiaľ rozšírenie nepoužíva iba háčiky). Šablóna môže používať dáta, ktoré pripojíte ku triede rozšírenia. Fava používa šablóny Jinja2, takže vo šablóne môžete vyrenderovať svoje dáta do HTML tabuľky alebo grafu.

Poznámka: Rozšírovací systém Fava je výkonný, ale považovaný za „nestabilný“ (môže sa meniť). Vyžaduje určitú znalosť webového vývoja (HTML/JS), ak vytvárate vlastné stránky. Ak je vaším cieľom len spúšťať skripty alebo analýzy, môže byť jednoduchšie ponechať ich ako externé skripty. Rozšírenia Fava používajte, keď chcete mať prispôsobený zážitok priamo v aplikácii pre váš pracovný tok.

Integrácia s API tretích strán a údajmi

Jednou z výhod skriptovateľných pracovných tokov je možnosť načítať vonkajšie údaje. Tu sú bežné integrácie:

  • Menové kurzy a komodity: Beancount zámerne nemanipuluje s automatickým sťahovaním cien (pre zachovanie deterministických reportov), ale poskytuje direktívu Price, pomocou ktorej môžete zadať kurzy. Môžete si automatizovať sťahovanie týchto cien. Napríklad skript môže volať API (Yahoo Finance, Alpha Vantage a pod.) pre najnovší kurz alebo cenu akcie a pridať záznam ceny do vášho denníka:

    2025-04-30 price BTC 30000 USD
    2025-04-30 price EUR 1.10 USD

    Existujú nástroje ako bea price, podporované Beanprice v spravovanom engine, ktoré sťahujú denný kurz a vyhadzujú ich vo formáte Beancount. Môžete ho raz aktivovať pomocou bea engine enable beanprice, potom naplánovať bea price main.beancount na spúšťanie každú noc, aby aktualizoval súbor prices.beancount. Alebo použiť Python: napr. s knižnicou requests na volanie API. Dokumentácia Beancount odporúča, že pre verejne obchodované aktíva môžete „vyvolať nejaký kód, ktorý stiahne ceny a zapíše za vás direktívy“. Inými slovami, nechajte skript vykonať vyhľadanie a vložiť riadky price, namiesto manuálneho zadávania.

  • Údaje o portfóliu akcií: Podobne ako pri menových kurzoch môžete integrovať API na získanie podrobných údajov o akciách alebo dividendách. Napríklad Yahoo Finance API (alebo komunitné knižnice ako yfinance) dokážu získať historické údaje pre ticker. Skript môže aktualizovať váš denník mesačnými cenami pre každú vlastnenú akciu, čím umožní presné historické reporty trhovej hodnoty. Niektoré vlastné rozšírenia (ako fava_investor) dokonca naživo načítavajú cenové údaje pre zobrazenie, ale najjednoduchšie je pravidelne importovať ceny do denníka.

  • Bankové API (Open Banking/Plaid): Namiesto sťahovania CSV súborov môžete použiť API na automatické získavanie transakcií. Služby ako Plaid agregujú bankové účty a umožňujú programatický prístup k transakciám. V pokročilom nastavení môžete mať Python skript, ktorý používa Plaid API na denný import nových transakcií a ich uloženie do súboru (alebo priamy import do hlavnej knihy). Jeden pokročilý používateľ vytvoril systém, kde Plaid napája jeho importný pipeline, čo ich účtovníctvo robí takmer automatickým. Uvádzajú, že „nič vám nebráni zaregistrovať sa s Plaid API a robiť to isté lokálne“ – teda môžete napísať lokálny skript na získavanie bankových údajov a potom použiť svoju Beancount importnú logiku na ich rozparsovanie do záznamov v knihe. Niektoré regióny majú otvorené bankové API poskytované bankami; tie je možné používať podobne.

  • Iné API: Môžete integrovať nástroje na rozpočet (export plánovaných rozpočtov na porovnanie s reálnymi údajmi v Beancount), alebo použiť OCR API na čítanie účteniek a automatické priradenie k transakciám. Keďže vaše skripty majú plný prístup k Python ekosystému, môžete integrovať všetko od e-mailových služieb (na odosielanie upozornení) cez Google Sheets (napr. aktualizácia tabuľky s mesačnými finančnými metrikami) až po komunikačné aplikácie (odoslanie súhrnnej správy cez Telegram bota).

Pri používaní API tretích strán nezabudnite zaistiť bezpečnosť vašich poverení (používajte premenné prostredia alebo konfiguračné súbory pre API kľúče) a v skriptoch elegantne spracovávať chyby (problémy so sieťou, výpadky API). Často je múdre cacheovať dáta (napríklad uložiť získané výmenné kurzy, aby ste nemuseli opakovane vyhľadávať rovnaký historický kurz).

Najlepšie praktiky pre modulárne, udržiavateľné skripty

Keď vytvárate skriptoateľné pracovné postupy, udržiavajte svoj kód usporiadaný a robustný:

  • Modularita: Rozdeľte rôzne záležitosti do samostatných skriptov alebo modulov. Napríklad vytvorte samostatné skripty pre „import/dohodovanie dát“ vs. „generovanie správ“ vs. „upozornenia“. Môžete dokonca vytvoriť malý Python balík pre vašu hlavnú knihu s modulmi ako ledger_import.py, ledger_reports.py a podobne. Každá časť je tak ľahšie pochopiteľná a testovateľná.

  • Konfigurácia: Vyhnite sa pevne zakódovaným hodnotám. Používajte konfiguračný súbor alebo premenné na začiatku skriptu pre veci ako názvy účtov, prahy, API kľúče, časové rozsahy a podobne. Uľahčuje to úpravy bez hlbokého zasahovania do kódu. Napríklad definujte LOW_BALANCE_THRESHOLDS = {"Assets:Bank:Checking": 500, "Assets:Savings": 1000} na začiatku a váš skript na upozornenia môže prechádzať cez túto slovníkovú štruktúru.

  • Testovanie: Zaobchádzajte s vašou finančnou automatizáciou ako s kódom kritickým pre misiu – pretože to naozaj je! Píšte testy pre zložitú logiku. Beancount poskytuje niektoré pomocné testovacie nástroje (používané interne na testovanie importérov), ktoré môžete využiť na simuláciu vstupov do knihy. Aj bez prepracovaných frameworkov môžete mať jednoduchý CSV a očakávané výstupné transakcie a overiť, či váš importný skript generuje správne zápisy. Ak používate pytest, môžete tieto testy ľahko integrovať (ako to urobil Alex Watt cez príkaz just test obalujúci pytest).

  • Verziovanie: Majte svoju knihu a skripty pod verziovacou kontrolou (git). Toto vám nielen zabezpečí zálohy a históriu, ale zároveň vás povzbudí robiť zmeny kontrolovaným spôsobom. Môžete si označovať vydania vašich „finančných skriptov“ alebo sledovať rozdiely pri ladení problémov. Niektorí používatelia dokonca sledujú svoje finančné záznamy v Gite, aby videli zmeny v čase. Len buďte opatrní a ignorujte citlivé údaje (ako surové výpisy alebo API kľúče) vo vašom repozitári.

  • Dokumentácia: Dokumentujte svoje vlastné pracovné postupy pre budúce použitie. README v repozitári vysvetľujúci, ako nastaviť prostredie, ako spustiť každý skript a čo každý robí, bude neoceniteľný po uplynutí niekoľkých mesiacov. Tiež komentujte svoj kód, najmä akúkoľvek nejasnú účtovnú logiku alebo interakciu s API.

  • Údržba pluginov Fava: Ak píšete rozšírenie pre Fava, udržujte ho jednoduché. Fava sa môže meniť, preto sú menšie rozšírenia s cieľovou funkcionalitou ľahšie na aktualizáciu. Vyvarujte sa duplicitnej logiky – používejte dotazovací engine Beancountu alebo existujúce pomocné funkcie všade tam, kde je to možné, namiesto toho, aby ste na pevno kódovali výpočty, ktoré môžu byť citlivé na zmeny v knihe.

  • Bezpečnosť: Keďže vaše skripty môžu spracovávať citlivé údaje a pripájať sa k externým službám, zaobchádzajte s nimi opatrne. Nezverejňujte API kľúče a zvážte spustenie automatizácie na bezpečnom zariadení. Ak používate hostované riešenie alebo cloud (napríklad plánovanie GitHub Actions alebo server na spustenie Fava), zabezpečte, aby boli vaše údaje z knihy zašifrované v pokoji a aby vám vyhovovali súvisiace súkromnostné dôsledky.

Dodržiavaním týchto postupov zabezpečíte, že váš pracovný proces zostane spoľahlivý aj keď sa vaše financie (a samotné nástroje) vyvíjajú. Chcete skripty, ktoré môžete rok čo rok znovu používať s minimálnymi úpravami.

Záver

Beancount a Fava poskytujú silnú, flexibilnú platformu pre technicky zdatných používateľov na úplné prispôsobenie sledovania osobných financií. Písaním Python skriptov môžete automatizovať únavné úlohy ako zosúladenie výpisov, vytvárať bohaté správy prispôsobené vašim potrebám a byť vždy v obraze so svojimi financiami vďaka včasným upozorneniam. Pokryli sme množstvo príkladov od základných po pokročilé – začínajúc jednoduchými dotazmi a importmi CSV, a pokračujúc plnohodnotnými Fava pluginmi a externými integráciami API. Pri implementácii začnite jednoducho a postupne rozširujte. Aj niekoľko malých automatizačných skriptov môže ušetriť hodiny práce a výrazne zlepšiť presnosť. A nezabúdajte, pretože všetko je v obyčajnom texte a Pythone, máte úplnú kontrolu – váš finančný systém rastie s vami, prispôsobujúc sa vašim špecifickým potrebám. Prajeme príjemné skriptovanie!

Zdroje: Techniky uvedené vyššie sú čerpané z dokumentácie Beancount a skúseností komunity. Pre ďalšie čítanie si pozrite oficiálnu dokumentáciu Beancount, komunitné návody a blogy, ako aj repozitár Awesome Beancount pre odkazy na užitočné pluginy a nástroje.

Zdroj: https://beancount.io/sk/docs/Solutions/scriptable-workflows