Skriptgesteuerte Arbeitsabläufe mit Beancount und Fava
Beancount (ein Plain-Text-Tool für die doppelte Buchführung) und Fava (seine Weboberfläche) sind hochgradig erweiterbar und skriptfähig. Ihr Design ermöglicht es Ihnen, Finanzaufgaben zu automatisieren, benutzerdefinierte Berichte zu erstellen und Warnmeldungen einzurichten, indem Sie Python-Skripte schreiben. In den Worten eines Benutzers: "Ich mag es sehr, meine Daten in einem so praktischen Format zu haben, und ich mag es, dass ich Dinge nach Herzenslust automatisieren kann. Es gibt keine API wie eine Datei auf Ihrer Festplatte; es ist einfach, sie zu integrieren." Dieser Leitfaden führt Sie durch die Erstellung skriptgesteuerter Arbeitsabläufe – von anfängerfreundlicher Automatisierung bis hin zu fortgeschrittenen Fava-Plugins.
Erste Schritte: Ausführen von Beancount als Python-Skript
Bevor Sie in bestimmte Aufgaben eintauchen, stellen Sie sicher, dass Beancount installiert ist (z. B. über pip install beancount). Da Beancount in Python geschrieben ist, können Sie es als Bibliothek in Ihren eigenen Skripten verwenden. Die allgemeine Vorgehensweise ist:
-
Laden Sie Ihr Beancount-Hauptbuch: Verwenden Sie den Beancount-Loader, um die
.beancount-Datei in Python-Objekte zu parsen. Zum Beispiel:from beancount import loader
entries, errors, options_map = loader.load_file("myledger.beancount")
if errors:
print("Errors:", errors)Dies gibt Ihnen eine Liste von
entries(Transaktionen, Salden usw.) und eineoptions_mapmit Metadaten. Alle Ihre Konten, Transaktionen und Salden sind jetzt im Code zugänglich. -
Nutzen Sie die Beancount Query Language (BQL): Anstatt manuell zu iterieren, können Sie SQL-ähnliche Abfragen auf den Daten ausführen. Um beispielsweise die gesamten Ausgaben pro Monat zu erhalten, können Sie die Abfrage-API verwenden:
from beancount.query import query
q = query.Query(entries, options_map)
result = q.query("SELECT month, sum(position) WHERE account ~ 'Expenses' GROUP BY month")
print(result)Dies verwendet das Abfragesystem von Beancount, um Daten zu aggregieren. (Im Wesentlichen ist dies ähnlich dem, was der Befehl
bean-querytut, aber hier verwenden Sie ihn in einem Skript.) Tatsächlich weist der Beancount-Autor darauf hin, dass Sie die Datei laden undrun_query()direkt über die Python-API aufrufen können, wodurch vermieden wird, externe Befehle in einer Schleife aufrufen zu müssen. -
Richten Sie eine Projektstruktur ein: Organisieren Sie Ihre Skripte zusammen mit Ihrem Hauptbuch. Ein gängiges Layout ist, Verzeichnisse für Importeure (zum Abrufen/Parsen externer Daten), Berichte oder Abfragen (für Analyseskripte) und Dokumente (zum Speichern heruntergeladener Kontoauszüge) zu haben. Ein Benutzer speichert beispielsweise:
importers/– benutzerdefinierte Python-Importskripte (mit Tests),queries/– Skripte zum Generieren von Berichten (ausführbar überpython3 queries/...),documents/– heruntergeladene Bank-CSVs/PDFs, organisiert nach Konto.
Mit dieser Einrichtung können Sie Skripte manuell ausführen (z. B. python3 queries/cash_flow.py) oder sie planen (über Cron oder einen Task-Runner), um Ihren Workflow zu automatisieren.
Automatisieren von Abstimmungsaufgaben
Abstimmung bedeutet, sicherzustellen, dass Ihr Hauptbuch mit externen Aufzeichnungen (Kontoauszüge, Kreditkartenabrechnungen usw.) übereinstimmt. Das Plain-Text-Hauptbuch und die Python-API von Beancount ermöglichen es, einen Großteil dieses Prozesses zu automatisieren.
Importieren und Abgleichen von Transaktionen (Anfänger)
Für Anfänger wird empfohlen, die Importer-Plugins von Beancount zu verwenden. Sie schreiben eine kleine Python-Klasse, die dem Beancount-Importer-Protokoll folgt, um ein bestimmtes Format (CSV, OFX, PDF usw.) zu parsen und Transaktionen zu erzeugen. Verwenden Sie dann den Befehl bean-extract oder ein Skript, um diese Importeure anzuwenden:
- Schreiben Sie einen Importeur (eine Python-Klasse mit Methoden wie
identify(),extract()) für das CSV-Format Ihrer Bank. Die Beancount-Dokumentation bietet eine Anleitung und Beispiele. - Verwenden Sie
bean-extractin einem Skript oder Makefile (wie dasjustfile-Beispiel), um neue Kontoauszüge zu parsen. Ein Workflow führt beispielsweisebean-extractfür alle Dateien in~/Downloadsaus und gibt Transaktionen in eine temporäre Datei aus. - Überprüfen und kopieren Sie Transaktionen manuell aus der temporären Datei in Ihr Hauptbuch und führen Sie dann
bean-checkaus, um sicherzustellen, dass die Salden übereinstimmen.
Obwohl dieser Prozess immer noch einen Überprüfungsschritt beinhaltet, wird ein Großteil der Routinearbeit des Parsens und Formatierens von Einträgen automatisiert. Importer-Skripte können auch automatisch Kategorien zuweisen und sogar Saldensicherungen (Aussagen erwarteter Salden) festlegen, um Unstimmigkeiten zu erkennen. Nach dem Importieren haben Sie beispielsweise eine Zeile wie 2025-04-30 balance Assets:Bank:Checking 1234.56 USD, die den Endsaldo bestätigt. Wenn Sie bean-check ausführen, überprüft Beancount, ob alle diese Saldensicherungen korrekt sind und meldet Fehler, wenn Transaktionen fehlen oder doppelt vorhanden sind. Dies ist eine Best Practice: Generieren Sie automatisch Saldensicherungen für jeden Abrechnungszeitraum, damit der Computer nicht abgeglichene Differenzen für Sie erkennen kann.
Benutzerdefinierte Abstimmungsskripte (Fortgeschritten)
Für mehr Kontrolle können Sie ein benutzerdefiniertes Python-Skript schreiben, um die Transaktionsliste einer Bank (CSV oder über API) mit Ihren Hauptbucheinträgen zu vergleichen:
- Lesen Sie die externen Daten: Parsen Sie die CSV-Datei der Bank mit dem Python-Modul
csv(oder Pandas). Normalisieren Sie die Daten in eine Liste von Transaktionen, z. B. jede mit Datum, Betrag und Beschreibung. - Laden Sie Hauptbuchtransaktionen: Verwenden Sie
loader.load_file, wie bereits gezeigt, um alle Hauptbucheinträge zu erhalten. Filtern Sie diese Liste nach dem relevanten Konto (z. B. Ihr Girokonto) und möglicherweise dem Datumsbereich des Kontoauszugs. - Vergleichen Sie und finden Sie Abweichungen:
- Überprüfen Sie für jede externe Transaktion, ob ein identischer Eintrag im Hauptbuch vorhanden ist (gleichen Sie Datum und Betrag, möglicherweise auch die Beschreibung ab). Wenn er nicht gefunden wird, markieren Sie ihn als "neu" und geben Sie ihn möglicherweise als Beancount-formatierte Transaktion zur Überprüfung aus.
- Identifizieren Sie umgekehrt alle Hauptbucheinträge in diesem Konto, die nicht in der externen Quelle erscheinen – dies könnten Dateneingabefehler oder Transaktionen sein, die noch nicht von der Bank beglichen wurden.
- Ausgabe der Ergebnisse: Geben Sie einen Bericht aus oder erstellen Sie einen neuen
.beancount-Ausschnitt mit den fehlenden Transaktionen.
Ein Community-Skript namens reconcile.py tut genau dies: Gegeben eine Beancount-Datei und eine Eingabe-CSV, gibt es eine Liste neuer Transaktionen aus, die importiert werden sollten, sowie alle vorhandenen Hauptbuchbuchungen, die nicht in der Eingabe enthalten sind (potenziell ein Zeichen für Fehlklassifizierung). Mit einem solchen Skript kann die monatliche Abstimmung so einfach sein, wie es auszuführen und dann die vorgeschlagenen Transaktionen an Ihr Hauptbuch anzuhängen. Ein Beancount-Benutzer merkt an, dass er "jeden Monat einen Abstimmungsprozess für alle Konten durchführt" und eine wachsende Sammlung von Python-Code verwendet, um einen Großteil der manuellen Arbeit beim Importieren und Abgleichen von Daten zu eliminieren.
Tipp: Nutzen Sie bei der Abstimmung die Tools von Beancount für Genauigkeit:
- Verwenden Sie Saldensicherungen, wie bereits erwähnt, um automatisierte Überprüfungen der Kontensalden zu haben.
- Verwenden Sie bei Bedarf die
pad-Direktive, die automatisch Ausgleichsbuchungen für geringfügige Rundungsdifferenzen einfügen kann (mit Vorsicht verwenden). - Schreiben Sie Unit-Tests für Ihre Importer- oder Abstimmungslogik (Beancount bietet Testhilfen). Ein Workflow beinhaltete beispielsweise das Nehmen einer Beispiel-CSV, das Schreiben von fehlgeschlagenen Tests mit erwarteten Transaktionen und dann das Implementieren des Importeurs, bis alle Tests bestanden waren. Dies stellt sicher, dass Ihr Importskript für verschiedene Fälle korrekt funktioniert.
Generieren von benutzerdefinierten Berichten und Zusammenfassungen
Während Fava viele Standardberichte (Gewinn- und Verlustrechnung, Bilanz usw.) bietet, können Sie mithilfe von Skripten benutzerdefinierte Berichte erstellen. Diese können von einfachen Konsolenausgaben bis hin zu reich formatierten Dateien oder Diagrammen reichen.
Abfragen von Daten für Berichte (Anfänger)
Auf grundlegender Ebene können Sie die Beancount Query Language (BQL) verwenden, um zusammenfassende Daten zu erhalten und sie auszudrucken oder zu speichern. Zum Beispiel:
-
Cashflow-Zusammenfassung: Verwenden Sie eine Abfrage, um den Netto-Cashflow zu berechnen. "Cashflow" könnte als die Veränderung des Saldos bestimmter Konten über einen Zeitraum definiert werden. Mit BQL könnten Sie Folgendes tun:
SELECT year, month, sum(amount)
WHERE account LIKE 'Income:%' OR account LIKE 'Expenses:%'
GROUP BY year, monthDies würde alle Einnahmen- und Ausgabenbuchungen nach Monat saldieren. Sie könnten dies über die
bean-query-CLI oder über die Python-API (query.Query, wie bereits gezeigt) ausführen und dann das Ergebnis formatieren. -
Kategorie-Ausgabenbericht: Abfrage der Gesamtausgaben pro Kategorie:
SELECT account, round(sum(position), 2)
WHERE account ~ 'Expenses'
GROUP BY account
ORDER BY sum(position) ASCDies ergibt eine Tabelle der Ausgaben nach Kategorie. Sie können mehrere Abfragen in einem Skript ausführen und die Ergebnisse als Text, CSV oder sogar JSON zur Weiterverarbeitung ausgeben.
Ein Benutzer fand es "trivial, Finanzdaten mit Fava oder mit Skripten zu analysieren", und erwähnte, dass er ein Python-Skript verwendet, um Daten über die Abfragesprache aus Beancount zu ziehen und sie dann in ein Pandas DataFrame zu legen, um einen benutzerdefinierten Bericht zu erstellen. Sie könnten beispielsweise monatliche Summen mit einer Abfrage abrufen und dann Pandas/Matplotlib verwenden, um ein Cashflow-Diagramm im Zeitverlauf zu erstellen. Die Kombination aus BQL und Data-Science-Bibliotheken ermöglicht es Ihnen, Berichte zu erstellen, die über das hinausgehen, was Fava standardmäßig bietet.
Erweiterte Berichterstellung (Diagramme, Performance usw.)
Für fortgeschrittenere Anforderungen können Ihre Skripte Metriken wie die Anlageperformance berechnen oder visuelle Ausgaben erstellen:
-
Anlageperformance (IRR/XIRR): Da Ihr Hauptbuch alle Cashflows (Käufe, Verkäufe, Dividenden) enthält, können Sie die Portfoliorenditen berechnen. Sie könnten beispielsweise ein Skript schreiben, das Transaktionen Ihrer Anlagekonten filtert und dann den internen Zinsfuß berechnet. Es gibt Bibliotheken (oder Formeln), um den IRR anhand von Cashflow-Daten zu berechnen. Einige von der Community entwickelte Fava-Erweiterungen (wie PortfolioSummary oder fava_investor) tun genau dies und berechnen den IRR und andere Metriken für Anlageportfolios. Als Skript könnten Sie eine IRR-Funktion (aus NumPy oder Ihrer eigenen) auf die Reihe von Beiträgen/Auszahlungen zuzüglich Endwert anwenden.
-
Mehrperioden- oder benutzerdefinierte Metriken: Möchten Sie einen Bericht über Ihre Sparquote (Verhältnis von Ersparnissen zu Einkommen) jeden Monat? Ein Python-Skript kann das Hauptbuch laden, alle Einnahmenkonten und alle Ausgabenkonten summieren und dann Ersparnisse = Einkommen - Ausgaben und den Prozentsatz berechnen. Dies könnte eine schöne Tabelle ausgeben oder sogar einen HTML-/Markdown-Bericht für Ihre Aufzeichnungen erstellen.
-
Visualisierung: Sie können Diagramme außerhalb von Fava generieren. Verwenden Sie beispielsweise
matplotliboderaltairin einem Skript, um ein Diagramm des Nettovermögens im Zeitverlauf zu erstellen, indem Sie Hauptbuchdaten verwenden. Da das Hauptbuch alle historischen Salden enthält (oder Sie sie durch Iterieren der Einträge ansammeln können), können Sie Zeitreihendiagramme erstellen. Speichern Sie diese Diagramme als Bilder oder interaktives HTML. (Wenn Sie Visualisierungen in der App bevorzugen, lesen Sie den Abschnitt zu Fava-Erweiterungen weiter unten, um Diagramme innerhalb von Fava hinzuzufügen.)
Ausgabeoptionen: Entscheiden Sie, wie Sie den Bericht bereitstellen möchten:
- Für einmalige Analysen kann es ausreichen, auf dem Bildschirm auszugeben oder in einer CSV-/Excel-Datei zu speichern.
- Für Dashboards sollten Sie die Generierung einer HTML-Datei mit den Daten in Betracht ziehen (möglicherweise unter Verwendung einer Templating-Bibliothek wie Jinja2 oder sogar nur durch Schreiben von Markdown), die Sie in einem Browser öffnen können.
- Sie können sich auch in Jupyter Notebooks für eine interaktive Berichtsumgebung integrieren, obwohl dies eher für die Erkundung als für die Automatisierung gedacht ist.
Auslösen von Warnmeldungen aus Ihrem Hauptbuch
Eine weitere leistungsstarke Verwendung skriptgesteuerter Arbeitsabläufe ist das Einrichten von Warnmeldungen basierend auf Bedingungen in Ihren Finanzdaten. Da Ihr Hauptbuch regelmäßig aktualisiert wird (und zukünftige Elemente wie anstehende Rechnungen oder Budgets enthalten kann), können Sie es mit einem Skript scannen und über wichtige Ereignisse benachrichtigt werden.
Warnungen bei niedrigem Kontostand
Um Überziehungen zu vermeiden oder einen Mindestkontostand aufrechtzuerhalten, möchten Sie möglicherweise eine Warnmeldung erhalten, wenn ein Konto (z. B. Giro oder Sparkonto) unter einen Schwellenwert fällt. So können Sie dies implementieren:
-
Bestimmen Sie die aktuellen Salden: Nachdem Sie
entriesüber den Loader geladen haben, berechnen Sie den letzten Saldo der betreffenden Konten. Sie können dies tun, indem Sie Buchungen aggregieren oder eine Abfrage verwenden. Verwenden Sie beispielsweise eine BQL-Abfrage für den Saldo eines bestimmten Kontos:SELECT sum(position) WHERE account = 'Assets:Bank:Checking'Dies gibt den aktuellen Saldo dieses Kontos zurück (Summe aller seiner Buchungen). Alternativ können Sie die internen Funktionen von Beancount verwenden, um eine Bilanz zu erstellen. Zum Beispiel:
from beancount.core import realization
tree = realization.realize(entries, options_map)
acct = realization.get_or_create(tree, "Assets:Bank:Checking")
balance = acct.balance # an Inventory of commoditiesExtrahieren Sie dann den numerischen Wert (z. B. könnte
balance.get_currency_units('USD')den Dezimalwert ergeben). Die Verwendung der Abfrage ist jedoch in den meisten Fällen einfacher. -
Überprüfen Sie den Schwellenwert: Vergleichen Sie den Saldo mit Ihrem vordefinierten Limit. Wenn er darunter liegt, lösen Sie eine Warnmeldung aus.
-
Auslösen der Benachrichtigung: Dies könnte so einfach sein wie das Ausgeben einer Warnung in der Konsole, aber für echte Warnmeldungen könnten Sie eine E-Mail oder Push-Benachrichtigung senden. Sie können sich in E-Mails integrieren (über
smtplib) oder in einen Dienst wie IFTTT oder die Webhook-API von Slack, um die Warnmeldung zu pushen. Zum Beispiel:if balance < 1000:
send_email("Low balance alert", f"Account XYZ balance is {balance}")(Implementieren Sie
send_emailmit Ihren E-Mail-Serverdetails.)
Indem Sie dieses Skript täglich ausführen (über einen Cron-Job oder den Windows Task Scheduler), erhalten Sie proaktive Warnungen. Da es das Hauptbuch verwendet, kann es alle Transaktionen berücksichtigen, einschließlich derer, die Sie gerade hinzugefügt haben.
Bevorstehende Zahlungstermine
Wenn Sie Beancount verwenden, um Rechnungen oder Termine zu verfolgen, können Sie zukünftige Zahlungen markieren und Skripte sich daran erinnern lassen. Zwei Möglichkeiten, bevorstehende Verpflichtungen in Beancount darzustellen:
-
Ereignisse: Beancount unterstützt eine
event-Direktive für beliebige datierte Notizen. Zum Beispiel:2025-05-10 event "BillDue" "Mortgage payment due"Dies wirkt sich nicht auf die Salden aus, sondern erfasst ein Datum mit einer Bezeichnung. Ein Skript kann
entriesnachEvent-Einträgen scannen, bei denenEvent.type == "BillDue"(oder ein anderer benutzerdefinierter Typ, den Sie wählen) und prüfen, ob das Datum innerhalb von z. B. den nächsten 7 Tagen ab heute liegt. Wenn ja, lösen Sie eine Warnmeldung aus (E-Mail, Benachrichtigung oder sogar ein Popup). -
Zukünftige Transaktionen: Einige Personen geben zukünftige Transaktionen (postdatiert) für Dinge wie geplante Zahlungen ein. Diese werden erst angezeigt, wenn das Datum verstrichen ist (es sei denn, Sie führen Berichte mit zukünftigen Daten aus). Ein Skript kann nach Transaktionen suchen, die in naher Zukunft datiert sind, und sie auflisten.
Mit diesen können Sie ein "Tickler"-Skript erstellen, das bei Ausführung eine Liste von Aufgaben oder Rechnungen ausgibt, die bald fällig sind. Integrieren Sie sich in eine API wie Google Kalender oder einen Aufgabenmanager, wenn Sie dort automatisch Erinnerungen erstellen möchten.
Anomalieerkennung
Über bekannte Schwellenwerte oder Daten hinaus können Sie benutzerdefinierte Warnmeldungen für ungewöhnliche Muster skripten. Wenn beispielsweise eine normalerweise monatliche Ausgabe nicht erfolgt ist (vielleicht haben Sie vergessen, eine Rechnung zu bezahlen) oder wenn die Ausgaben einer Kategorie diesen Monat ungewöhnlich hoch sind, könnte Ihr Skript dies kennzeichnen. Dies beinhaltet in der Regel das Abfragen der letzten Daten und den Vergleich mit der Historie (was ein fortgeschrittenes Thema sein könnte – möglicherweise unter Verwendung von Statistiken oder ML).
In der Praxis verlassen sich viele Benutzer auf die Abstimmung, um Anomalien zu erkennen (unerwartete Transaktionen). Wenn Sie Bankbenachrichtigungen erhalten (z. B. E-Mails für jede Transaktion), könnten Sie diese mit einem Skript parsen und automatisch zu Beancount hinzufügen oder zumindest überprüfen, ob sie erfasst wurden. Ein Enthusiast hat sogar seine Bank so konfiguriert, dass sie E-Mail-Benachrichtigungen über Transaktionen sendet, mit dem Plan, sie zu parsen und automatisch an das Hauptbuch anzuhängen. Diese Art von ereignisgesteuerter Warnung kann sicherstellen, dass keine Transaktion unerfasst bleibt.
Erweitern von Fava mit benutzerdefinierten Plugins und Ansichten
Fava ist bereits über sein Erweiterungssystem skriptfähig. Wenn Sie möchten, dass Ihre Automatisierung oder Berichte direkt in die Weboberfläche integriert werden, können Sie eine Fava-Erweiterung (auch Plugin genannt) in Python schreiben.
So funktionieren Fava-Erweiterungen: Eine Erweiterung ist ein Python-Modul, das eine Klasse definiert, die von fava.ext.FavaExtensionBase erbt. Sie registrieren sie in Ihrer Beancount-Datei über eine benutzerdefinierte Option. Wenn Sie beispielsweise eine Datei myextension.py mit einer Klasse MyAlerts(FavaExtensionBase) haben, können Sie sie aktivieren, indem Sie Folgendes zu Ihrem Hauptbuch hinzufügen:
1970-01-01 custom "fava-extension" "myextension"
Wenn Fava geladen wird, importiert es dieses Modul und initialisiert Ihre MyAlerts-Klasse.
Erweiterungen können verschiedene Dinge tun:
- Hooks: Sie können sich in Ereignisse im Lebenszyklus von Fava einklinken. Beispielsweise wird
after_load_file()aufgerufen, nachdem das Hauptbuch geladen wurde. Sie könnten dies verwenden, um Überprüfungen durchzuführen oder Daten vorzuberechnen. Wenn Sie die Überprüfung auf niedrigen Kontostand innerhalb von Fava implementieren möchten, könnteafter_load_fileüber die Kontostände iterieren und möglicherweise Warnungen speichern (obwohl das Anzeigen in der Benutzeroberfläche etwas mehr Arbeit erfordern könnte, z. B. das Auslösen eines FavaAPIError oder die Verwendung von Javascript, um eine Benachrichtigung anzuzeigen). - Benutzerdefinierte Berichte/Seiten: Wenn Ihre Erweiterungsklasse ein Attribut
report_titlesetzt, fügt Fava eine neue Seite in der Seitenleiste dafür hinzu. Sie stellen dann eine Vorlage (HTML/Jinja2) für den Inhalt dieser Seite bereit. Auf diese Weise erstellen Sie völlig neue Ansichten, z. B. ein Dashboard oder eine Zusammenfassung, die Fava nicht standardmäßig hat. Die Erweiterung kann alle Daten sammeln, die sie benötigt (Sie können aufself.ledgerzugreifen, das alle Einträge, Salden usw. enthält) und dann die Vorlage rendern.
Beispielsweise fügt die integrierte portfolio_list-Erweiterung in Fava eine Seite hinzu, die Ihre Portfoliopositionen auflistet. Community-Erweiterungen gehen noch weiter:
- Dashboards: Das fava-dashboards-Plugin ermöglicht das Definieren von benutzerdefinierten Diagrammen und Panels (unter Verwendung von Bibliotheken wie Apache ECharts). Es liest eine YAML-Konfiguration von auszuführenden Abfragen, führt sie über Beancount aus und generiert eine dynamische Dashboard-Seite in Fava. Im Wesentlichen verbindet es Beancount-Daten und eine JavaScript-Diagrammbibliothek, um interaktive Visualisierungen zu erstellen.
- Portfolioanalyse: Die PortfolioSummary-Erweiterung (von Benutzern beigetragen) berechnet Anlagezusammenfassungen (Gruppierung von Konten, Berechnung des IRR usw.) und zeigt sie in der Fava-Benutzeroberfläche an.
- Transaktionsprüfung: Eine weitere Erweiterung, fava-review, hilft bei der Überprüfung von Transaktionen im Zeitverlauf (z. B. um sicherzustellen, dass Sie keine Belege verpasst haben).
Um selbst eine einfache Erweiterung zu erstellen, beginnen Sie mit dem Subclassing von FavaExtensionBase. Eine minimale Erweiterung, die eine Seite hinzufügt, könnte beispielsweise wie folgt aussehen:
from fava.ext import FavaExtensionBase
class HelloReport(FavaExtensionBase):
report_title = "Hallo Welt"
def __init__(self, ledger, config):
super().__init__(ledger, config)
# jegliche Initialisierung, evtl. Parsen der Konfiguration, falls angegeben
def after_load_file(self):
# (optional) nach dem Laden des Hauptbuchs ausführen
print("Hauptbuch geladen mit", len(self.ledger.entries), "Einträgen")
Wenn Sie dies in hello.py platziert und custom "fava-extension" "hello" zu Ihrem Hauptbuch hinzugefügt haben, würde Fava eine neue Seite "Hallo Welt" anzeigen (Sie benötigen auch eine Vorlagendatei HelloReport.html in einem Unterordner templates, um den Seiteninhalt zu definieren, es sei denn, die Erweiterung verwendet nur Hooks). Die Vorlage kann Daten verwenden, die Sie an die Erweiterungsklasse anhängen. Fava verwendet Jinja2-Vorlagen, sodass Sie Ihre Daten in dieser Vorlage in eine HTML-Tabelle oder ein Diagramm rendern können.
Hinweis: Das Erweiterungssystem von Fava ist leistungsstark, gilt aber als "instabil" (Änderungen vorbehalten). Es erfordert einige Vertrautheit mit der Webentwicklung (HTML/JS), wenn Sie benutzerdefinierte Seiten erstellen. Wenn Ihr Ziel einfach darin besteht, Skripte oder Analysen auszuführen, ist es möglicherweise einfacher, sie als externe Skripte zu behalten. Verwenden Sie Fava-Erweiterungen, wenn Sie eine maßgeschneiderte In-App-Erfahrung für Ihren Workflow wünschen.
Integrieren von Drittanbieter-APIs und -Daten
Einer der Vorteile skriptgesteuerter Arbeitsabläufe ist die Möglichkeit, externe Daten abzurufen. Hier sind gängige Integrationen:
-
Wechselkurse & Rohstoffe: Beancount ruft Preise standardmäßig nicht automatisch ab (um Berichte deterministisch zu halten), aber es stellt eine Price-Direktive bereit, mit der Sie Kurse angeben können. Sie können das Abrufen dieser Preise automatisieren. Ein Skript kann beispielsweise eine API (Yahoo Finance, Alpha Vantage usw.) nach dem neuesten Wechselkurs oder Aktienkurs abfragen und einen Preiseintrag an Ihr Hauptbuch anhängen:
2025-04-30 price BTC 30000 USD
2025-04-30 price EUR 1.10 USDEs gibt Tools wie
bean-price(jetzt ein externes Tool unter dem Dach von Beancount), die täglich Kurse abrufen und im Beancount-Format ausgeben. Sie könntenbean-priceso planen, dass es jede Nacht ausgeführt wird, um eineprices.beancount-Include-Datei zu aktualisieren. Oder verwenden Sie Python: z. B. mit derrequests-Bibliothek, um eine API aufzurufen. Die Beancount-Dokumentation schlägt vor, dass Sie für öffentlich gehandelte Vermögenswerte "etwas Code aufrufen können, der Preise herunterlädt und die Direktiven für Sie ausgibt." Mit anderen Worten, lassen Sie ein Skript die Suche durchführen und dieprice-Zeilen einfügen, anstatt es manuell zu tun. -
Aktienportfolio-Daten: Ähnlich wie bei Wechselkursen können Sie sich in APIs integrieren, um detaillierte Aktiendaten oder Dividenden abzurufen. Beispielsweise kann die Yahoo Finance API (oder Community-Bibliotheken wie
yfinance) historische Daten für einen Ticker abrufen. Ein Skript könnte Ihr Hauptbuch mit monatlicher Kurshistorie für jede Aktie aktualisieren, die Sie besitzen, wodurch genaue historische Berichte über den Marktwert ermöglicht werden. Einige benutzerdefinierte Erweiterungen (wie fava_investor) rufen sogar Kursdaten ad hoc zur Anzeige ab, aber am einfachsten ist es, Preise regelmäßig in das Hauptbuch zu importieren. -
Banking-APIs (Open Banking/Plaid): Anstatt CSVs herunterzuladen, können Sie APIs verwenden, um Transaktionen automatisch abzurufen. Dienste wie Plaid aggregieren Bankkonten und ermöglichen den programmgesteuerten Zugriff auf Transaktionen. In einer fortgeschrittenen Einrichtung könnten Sie ein Python-Skript haben, das die Plaid-API verwendet, um täglich neue Transaktionen abzurufen und sie in einer Datei zu speichern (oder direkt in das Hauptbuch zu importieren). Ein Power-User baute ein System, bei dem Plaid in seine Import-Pipeline einfließt, wodurch seine Bücher fast automatisch geführt werden. Er merkt an, dass "nichts Sie daran hindert, sich bei der Plaid-API anzumelden und dasselbe lokal zu tun" – d. h., Sie können ein lokales Skript schreiben, um Bankdaten abzurufen, und dann Ihre Beancount-Importer-Logik verwenden, um sie in Hauptbucheinträge zu parsen. Einige Regionen haben Open-Banking-APIs, die von Banken bereitgestellt werden; diese könnten auf ähnliche Weise verwendet werden.
-
Andere APIs: Sie könnten Budgetierungstools integrieren (geplante Budgets exportieren, um sie mit den tatsächlichen Werten in Beancount zu vergleichen) oder eine OCR-API verwenden, um Belege zu lesen und sie automatisch mit Transaktionen abzugleichen. Da Ihre Skripte vollen Zugriff auf das Python-Ökosystem haben, können Sie alles von E-Mail-Diensten (zum Senden von Warnmeldungen) über Google Sheets (z. B. Aktualisieren eines Blatts mit monatlichen Finanzkennzahlen) bis hin zu Messaging-Apps integrieren (Senden Sie sich einen zusammenfassenden Bericht über einen Telegram-Bot).
Denken Sie bei der Verwendung von Drittanbieter-APIs daran, Ihre Anmeldeinformationen zu sichern (verwenden Sie Umgebungsvariablen oder Konfigurationsdateien für API-Schlüssel) und Fehler (Netzwerkprobleme, API-Ausfallzeiten) in Ihren Skripten ordnungsgemäß zu behandeln. Es ist oft ratsam, Daten zu cachen (z. B. abgerufene Wechselkurse zu speichern, damit Sie denselben historischen Kurs nicht wiederholt anfordern).
Best Practices für modulare, wartbare Skripte
Wenn Sie skriptgesteuerte Arbeitsabläufe erstellen, halten Sie Ihren Code organisiert und robust:
-
Modularität: Teilen Sie verschiedene Belange in verschiedene Skripte oder Module auf. Erstellen Sie beispielsweise separate Skripte für "Datenimport/-abgleich" vs. "Berichtsgenerierung" vs. "Warnmeldungen". Sie können sogar ein kleines Python-Paket für Ihr Hauptbuch mit Modulen wie
ledger_import.py,ledger_reports.pyusw. erstellen. Dies macht jeden Teil leichter verständlich und testbar. -
Konfiguration: Vermeiden Sie das Hartcodieren von Werten. Verwenden Sie eine Konfigurationsdatei oder Variablen am Anfang des Skripts für Dinge wie Kontonamen, Schwellenwerte, API-Schlüssel, Datumsbereiche usw. Dies erleichtert das Anpassen, ohne den Code tiefgreifend bearbeiten zu müssen. Definieren Sie beispielsweise
LOW_BALANCE_THRESHOLDS = {"Assets:Bank:Checking": 500, "Assets:Savings": 1000}am Anfang, und Ihr Warnskript kann diese Liste durchlaufen. -
Testen: Behandeln Sie Ihre Finanzautomatisierung als geschäftskritischen Code – denn das ist sie! Schreiben Sie Tests für komplexe Logik. Beancount bietet einige Testhilfen (die intern für das Testen von Importeuren verwendet werden), die Sie nutzen können, um Hauptbucheingaben zu simulieren. Auch ohne ausgefallene Frameworks können Sie eine Dummy-CSV und erwartete Ausgabetransaktionen haben und sicherstellen, dass Ihr Importskript die korrekten Einträge erzeugt. Wenn Sie
pytestverwenden, können Sie diese Tests einfach integrieren (wie Alex Watt über einenjust test-Befehl tat, der pytest umschließt). -
Versionskontrolle: Bewahren Sie Ihr Hauptbuch und Ihre Skripte unter Versionskontrolle (git) auf. Dies bietet Ihnen nicht nur Backups und Historie, sondern ermutigt Sie auch, Änderungen auf kontrollierte Weise vorzunehmen. Sie können Releases Ihrer "Finanzskripte" markieren oder Unterschiede überprüfen, wenn Sie ein Problem debuggen. Einige Benutzer verfolgen ihre Finanzunterlagen sogar in Git, um Änderungen im Zeitverlauf zu sehen. Achten Sie nur darauf, sensible Daten (wie rohe Kontoauszugsdateien oder API-Schlüssel) in Ihrem Repo zu ignorieren.
-
Dokumentation: Dokumentieren Sie Ihre benutzerdefinierten Arbeitsabläufe für Ihr zukünftiges Ich. Eine README-Datei in Ihrem Repository, die erklärt, wie Sie die Umgebung einrichten, wie Sie jedes Skript ausführen und was jedes Skript tut, wird nach Monaten unschätzbar wertvoll sein. Kommentieren Sie auch Ihren Code, insbesondere alle nicht offensichtlichen Buchhaltungslogiken oder API-Interaktionen.
-
Wartung von Fava-Plugins: Wenn Sie eine Fava-Erweiterung schreiben, halten Sie sie einfach. Fava könnte sich ändern, sodass kleinere Erweiterungen mit gezielter Funktionalität leichter zu aktualisieren sind. Vermeiden Sie es, zu viel Logik zu duplizieren – verwenden Sie die Abfrage-Engine von Beancount oder vorhandene Hilfsfunktionen, wann immer möglich, anstatt Berechnungen hart zu codieren, die möglicherweise empfindlich auf Hauptbuchänderungen reagieren.
-
Sicherheit: Da Ihre Skripte möglicherweise sensible Daten verarbeiten und sich mit externen Diensten verbinden, behandeln Sie sie mit Sorgfalt. Geben Sie keine API-Schlüssel preis und erwägen Sie, Ihre Automatisierung auf einem sicheren Rechner auszuführen. Wenn Sie eine gehostete Lösung oder Cloud verwenden (z. B. das Planen von GitHub Actions oder eines Servers zum Ausführen von Fava), stellen Sie sicher, dass Ihre Hauptbuchdaten im Ruhezustand verschlüsselt sind und dass Sie mit den Auswirkungen auf den Datenschutz einverstanden sind.
Durch das Befolgen dieser Praktiken stellen Sie sicher, dass Ihr Workflow zuverlässig bleibt, auch wenn sich Ihre Finanzen (und die Tools selbst) weiterentwickeln. Sie möchten Skripte, die Sie Jahr für Jahr mit minimalen Anpassungen wiederverwenden können.
Fazit
Beancount und Fava bieten eine leistungsstarke, flexible Plattform für technisch versierte Benutzer, um ihre persönliche Finanzverfolgung vollständig anzupassen. Durch das Schreiben von Python-Skripten können Sie mühsame Aufgaben wie das Abgleichen von Kontoauszügen automatisieren, umfangreiche Berichte erstellen, die auf Ihre Bedürfnisse zugeschnitten sind, und mit zeitnahen Warnmeldungen den Überblick über Ihre Finanzen behalten. Wir haben eine Reihe von Beispielen von einfach bis fortgeschritten behandelt – beginnend mit einfachen Abfragen und CSV-Importen und übergehend zu vollwertigen Fava-Plugins und externen API-Integrationen. Beginnen Sie bei der Implementierung einfach und bauen Sie sie schrittweise auf. Selbst ein paar kleine Automatisierungsskripte können Stunden an Arbeit sparen und die Genau