Beancount(プレーンテキストの複式簿記ツール)とFava(そのWebインターフェース)は、高い拡張性とスクリプト可能性を備えています。その設計により、Pythonスクリプトを書くことで財務タスクの自動化、カスタムレポートの生成、アラートの設定が可能になります。あるユーザーの言葉を借りれば、"データがこんなに便利な形式で手に入り、好きなだけ自動化できるのが本当に気に入っています。ディスク上のファイルに勝るAPIはありません。統合も簡単です。" このガイドでは、初心者向けの自動化から高度なFavaプラグインまで、スクリプト可能なワークフローの作成方法を順を追って説明します。
実際のサンプル台帳を見てみましょう:
bea コマンドラインから始める
Pythonを書く前に、beaがすでにその仕事をしてくれないか確認してください。台帳の検証、BQLクエリの実行、4つの財務レポートの生成、銀行のエクスポートのインポートができ、グローバルな--jsonオプションを使えば、それぞれをシェルでjqにパイプできる解析可能なエンベロープに変換できます。終了コードはスケジュールされたジョブが分岐するための契約であり、cronやCIでローダースクリプトは不要です。beaで簿記を自動化するを参照して、ターゲットの解決、エンベロープ、終了コードの分岐について確認し、CLIが公開していないカスタム計算が必要になったら、ここに戻ってきてください。
はじめに: BeancountをPythonスクリプトとして実行する
以下のカスタムPythonスクリプトでは、スクリプト用ライブラリをインストールしてください(pip install beancount beanquery beangulp)。beaコマンドのワークフローでは管理エンジンを使用します。CLIクイックスタートに従ってインストールしてください。BeancountはPythonで書かれているため、独自のスクリプトでライブラリとして使用できます。以下のスクリプトはBeancount 3.2.3、beanquery 0.2.0、beangulp 0.2.0で実行されました。一般的なアプローチは次のとおりです。
-
Beancountの台帳を読み込む: Beancountのローダーを使用して
.beancountファイルをPythonオブジェクトに解析します。例:from beancount import loader entries, errors, options = loader.load_file("myledger.beancount") if errors: for error in errors: print(error) raise SystemExit(1)ローダーはentriesとerrorsを一緒に返します。バランスが取れていない、または無効なファイルでもentriesは返されるため、
errorsを確認してからデータを信頼してください。すべての勘定科目、取引、残高がコードでアクセス可能になります。 -
Beancountクエリ言語(BQL)を活用する: 手動で反復処理する代わりに、データに対してSQLライクなクエリを実行できます。クエリは別の
beanqueryパッケージにあります。Beancount 3.2.3にはbeancount.queryモジュールはありません。たとえば、月ごとの総支出を取得するには、読み込んだentriesを接続してクエリを直接実行します。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)これはbeanqueryを使用してデータを集計します。
bea queryの背後にある同じエンジンですが、ここではスクリプト内で呼び出しています。これにより、ループ内で外部コマンドを呼び出す必要がなくなります。 -
プロジェクト構造を設定する: 台帳の隣にスクリプトを整理します。一般的なレイアウトとしては、importers(外部データの取得・解析用)、reportsまたはqueries(分析スクリプト用)、documents(ダウンロードした明細書類の保存用)のディレクトリがあります。たとえば、あるユーザーは次のように管理しています。
importers/– カスタムPythonインポートスクリプト(テスト付き)、queries/– レポート生成用スクリプト(python3 queries/...で実行可能)、documents/– アカウントごとに整理されたダウンロード済み銀行CSV/PDF。
この設定により、スクリプトを手動で実行(例:
python3 queries/cash_flow.py)したり、cronやタスクランナーでスケジュールしてワークフローを自動化できます。
調整(リコンサイル)タスクの自動化
リコンサイルとは、台帳が外部記録(銀行明細書、クレジットカードレポートなど)と一致していることを確認することを意味します。Beancountのプレーンテキスト台帳とPython APIにより、このプロセスの多くを自動化することが可能です。
取引のインポートとマッチング(初心者向け)
初心者には、別パッケージbeangulpのインポーターを使用することをお勧めします。Beancount 3ではv2の取り込みモジュールとそのextractコマンドが削除されました。beangulp.Importerをサブクラス化した小さなPythonクラスを書いて、特定の形式(CSV、OFX、PDFなど)を解析し、取引を生成します。それを短い取り込みスクリプトに登録し、管理エンジンでbea ingestを通じて実行します。
- あなたの銀行のCSV形式用のインポーター(
identify()、account()、extract()メソッドを持つPythonクラス)を書きます。 - インポーターを登録する取り込みスクリプトを追加します。
bea ingestはスクリプトのidentify、extract、archiveコマンドを実行します。たとえば、あるワークフローでは~/Downloads内の全ファイルに対してextractを実行し、取引を一時ファイルに出力します。 - 一時ファイルから取引を手動で確認してメインの台帳にコピーし、
bea checkを実行して残高が整合することを確認します。
最小限の例:date,description,amount列を持つstatement.csvを、次のインポーター(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.py)はそれを接続します:
from checking_importer import CheckingImporter
from beangulp import Ingest
ingest = Ingest([CheckingImporter()])
if __name__ == "__main__":
ingest()ダウンロードしたファイルに対して実行します。ローカルCSVには資格情報は不要です。まずシステムのlibmagicライブラリをインストールしてください。一度だけ有効化するコマンドで、Beangulpを管理エンジンにダウンロードします:
bea engine enable beangulp
bea ingest identify --config ingest.py statement.csv
bea ingest extract --config ingest.py statement.csv -o new.beancountidentifyはファイルに対してchecking_importer.CheckingImporterを報告します。extractはBeancount形式で取引を書き出します:
2024-01-08 * "Grocery Store"
Expenses:Food:Groceries 120.00 USD
Assets:Bank:Checking -120.00 USDnew.beancountを確認し、エントリをメインの台帳にコピーして、bea checkを実行します。
単一の明細を変換するためにインポーターを書く必要はありません。ファイルをCSVからBeancountへのコンバーターに貼り付けるか、.ofx、.qfx、.qifのダウンロードにはOFX & QIFからBeancountへを使用してください。どちらもブラウザ内で完全に実行されるため、明細があなたのマシンから出ることはありません。
このプロセスにはまだ確認ステップが含まれますが、エントリの解析とフォーマットの多くの単純作業は自動化されています。インポータースクリプトはカテゴリを自動割り当てしたり、残高のアサーション(期待残高のステートメント)を設定して不一致を検出することもできます。たとえば、インポート後、2025-04-30 balance Assets:Bank:Checking 1234.56 USDのような行があるかもしれません。これは期末残高をアサートします。bea checkを実行すると、Beancountは_これらのすべての残高アサーションが正しいかどうかを検証し_、取引が欠落または重複している場合にエラーをフラグします。これはベストプラクティスです。各明細期間ごとに残高アサーションを自動生成して、コンピューターに未調整の差異を発見させましょう。
カスタム調整スクリプト(中級)
より詳細な制御が必要な場合は、銀行の取引リスト(CSVまたはAPI経由)と台帳エントリを比較するカスタムPythonスクリプトを書くことができます:
- 外部データを読み取る: Pythonの
csvモジュール(またはPandas)を使用して銀行のCSVファイルを解析します。データを取引リスト(各取引に日付、金額、説明)に正規化します。 - 台帳取引を読み込む: 前述のように
loader.load_fileを使用してすべての台帳エントリを取得します。このリストを対象の勘定科目(例:当座預金口座)や、明細の日付範囲にフィルタリングします。 - 比較して不一致を見つける:
- 外部取引ごとに、台帳に同一のエントリが存在するか確認します(日付と金額、場合によっては説明でマッチ)。見つからない場合は「新規」としてマークし、確認用にBeancount形式の取引として出力する可能性があります。
- 逆に、その勘定科目内で外部ソースに存在しない台帳エントリを特定します。これらはデータ入力エラーや、銀行でまだ清算されていない取引の可能性があります。
- 結果を出力する: レポートを印刷するか、欠落した取引を含む新しい
.beancountスニペットを作成します。
たとえば、コミュニティスクリプトの reconcile.py はまさにこれを行います:Beancountファイルと入力CSVが与えられると、インポートすべき新しい取引のリストと、入力にない既存の台帳ポスティング(誤分類の兆候)を印刷します。このようなスクリプトを使えば、毎月の調整はスクリプトを実行して、提案された取引を台帳に追加するだけで済みます。あるBeancountユーザーは、"毎月すべての口座で調整プロセスを行っており"、データのインポートと調整の手作業の多くを排除するために、増え続けるPythonコードのコレクションを使用していると述べています。
ヒント: 調整中は、正確性のためにBeancountのツールを活用してください:
- 前述の残高アサーションを使用して、口座残高の自動チェックを行います。
- 必要に応じて
padディレクティブを使用します。これはわずかな丸め差を埋めるバランシングエントリを自動挿入できます(注意して使用してください)。 - インポーターや調整ロジックの単体テストを書きます(Beancountにはテストヘルパーがあります)。たとえば、あるワークフローでは、サンプルCSVを取り、期待される取引を含む失敗するテストを書き、すべてのテストが通るまでインポーターを実装しました。これにより、インポートスクリプトがさまざまなケースで正しく動作することが保証されます。
カスタムレポートとサマリーの生成
Favaは多くの標準レポート(損益計算書、貸借対照表など)を提供しますが、スクリプトを使用してカスタムレポートを作成できます。これらは、シンプルなコンソール出力から、リッチなフォーマット済みファイルやチャートまでさまざまです。
レポート用データのクエリ(初心者向け)
基本的なレベルでは、Beancountクエリ言語(BQL)を使用してサマリーデータを取得し、印刷または保存できます。例:
-
キャッシュフローサマリー: クエリを使用して純キャッシュフローを計算します。「キャッシュフロー」は、特定の期間における特定の勘定科目の残高の変化として定義できます。BQLを使用すると、次のようになります:
SELECT year, month, sum(position) WHERE account ~ 'Income' OR account ~ 'Expenses' GROUP BY year, monthこれにより、すべての収入と支出のポスティングが月ごとに純額で合計されます。
~と正規表現でフィルタリングします:beanquery 0.2.0ではLIKEは構文エラーです。ポスティングはamountではなくpositionを保持します。各行は1つのインベントリを保持するため、各通貨は変換されずに個別にリストされます。収入は負、支出は正になります。これはbea queryまたは前述のbeanquery Python APIを通じて実行し、結果をフォーマットできます。 -
カテゴリ別支出レポート: カテゴリごとの総支出をクエリします:
SELECT account, sum(position) WHERE account ~ 'Expenses' GROUP BY account ORDER BY sum(position) ASCこれにより、カテゴリ別の支出テーブルが得られます。各合計は元の通貨のインベントリです。集計を
round()でラップしないでください:round(inventory, int)関数はないため、round(sum(position), 2)はコンパイルに失敗します。スクリプトで複数のクエリを実行し、結果をテキスト、CSV、さらにはJSONとして出力してさらに処理できます。
あるユーザーは、Favaやスクリプトで財務データを分析するのは_"簡単"_だと述べ、クエリ言語でBeancountからデータを取得し、Pandas DataFrameに入れてカスタムレポートを準備するPythonスクリプトを1つ使用していると述べています。たとえば、月次合計をクエリで取得し、Pandas/Matplotlibを使用して時間経過によるキャッシュフローチャートをプロットできます。BQLとデータサイエンスライブラリの組み合わせにより、Favaがデフォルトで提供する以上のレポートを構築できます。
高度なレポート(チャート、パフォーマンスなど)
より高度なニーズには、スクリプトで投資パフォーマンスなどのメトリクスを計算したり、視覚的な出力を作成したりできます:
-
投資パフォーマンス(IRR/XIRR): 台帳にはすべてのキャッシュフロー(売買、配当)が含まれているため、ポートフォリオのリターン率を計算できます。たとえば、投資口座の取引をフィルタリングし、内部収益率(IRR)を計算するスクリプトを書くことができます。キャッシュフローデータからIRRを計算するライブラリ(または公式)があります。コミュニティ開発のFava拡張機能(PortfolioSummaryやfava_investorなど)はまさにこれを行い、投資ポートフォリオのIRRやその他のメトリクスを計算します。スクリプトとしては、貢献/引き出しの系列と期末価値にIRR関数(NumPyまたは独自のもの)を使用できます。
-
複数期間またはカスタムメトリクス: 毎月の貯蓄率(収入に対する貯蓄の比率)のレポートが必要ですか?Pythonスクリプトで台帳を読み込み、すべての収入勘定科目と支出勘定科目を合計し、貯蓄 = 収入 - 支出、そしてパーセンテージを計算できます。これは見栄えの良いテーブルを出力したり、記録用にHTML/Markdownレポートを生成したりできます。
-
可視化: Favaの外でチャートを生成できます。たとえば、スクリプトで
matplotlibやaltairを使用して、台帳データから純資産の時間経過チャートを作成できます。台帳にはすべての履歴残高があるため(またはエントリを反復処理して累積できます)、時系列プロットを生成できます。これらのチャートを画像やインタラクティブなHTMLとして保存します。(アプリ内のビジュアルがお好みの場合は、以下のFava拡張セクションを参照して、Fava_内に_チャートを追加してください。)
出力オプション: レポートの配信方法を決定します:
- 一度きりの分析には、画面に印刷したりCSV/Excelファイルに保存するので十分かもしれません。
- ダッシュボードには、データを含むHTMLファイルを生成することを検討してください(Jinja2などのテンプレートライブラリを使用するか、単にMarkdownを書くだけでも可)。ブラウザで開くことができます。
- インタラクティブなレポート環境にはJupyter Notebooksと統合することもできますが、これは自動化というより探索向けです。
台帳からのアラート発動
スクリプト可能なワークフローのもう1つの強力な用途は、財務データの条件に基づくアラートの設定です。台帳が定期的に更新され(将来日付の項目、たとえば未払いの請求書や予算を含めることができます)、スクリプトでスキャンして重要なイベントを通知できます。
低残高警告
当座預金の引き落としを防いだり、最低残高を維持するには、いずれかの勘定科目(例:当座預金、普通預金)がしきい値を下回った場合にアラートが必要かもしれません。実装方法は次のとおりです:
-
現在の残高を決定する: ローダーで
entriesを読み込んだ後、対象の勘定科目の最新残高を計算します。ポスティングを集計するかクエリを使用します。たとえば、特定の勘定科目の残高を取得するBQLクエリ:SELECT sum(position) WHERE account = 'Assets:Bank:Checking'これはその勘定科目の現在の残高(すべてのポスティングの合計)を返します。代わりに、Beancountの内部関数を使用してバランスシートを構築することもできます。たとえば:
from beancount.core import realization tree = realization.realize(entries) acct = realization.get_or_create(tree, "Assets:Bank:Checking") balance = acct.balance # an Inventory of commoditiesentriesのみを渡します:2番目のパラメータは
min_accountsであり、オプションマップではありません。次に数値を抽出します(例:balance.get_currency_units('USD')はUSDのDecimal額を返します)。クエリ集計と同様に、残高は通貨ごとに個別に保持されます。ただし、ほとんどの場合、クエリの方が簡単です。 -
しきい値を確認する: 残高を事前定義した制限と比較します。下回っている場合はアラートを発動します。
-
通知をトリガーする: これはコンソールに警告を印刷するだけでも構いませんが、実際のアラートにはメールやプッシュ通知を送信することをお勧めします。メール(
smtplib経由)またはIFTTTやSlackのwebhook APIなどのサービスと統合してアラートをプッシュできます。たとえば:if balance < 1000: send_email("Low balance alert", f"Account XYZ balance is {balance}")(
send_emailをメールサーバーの詳細で実装してください。)このスクリプトを毎日実行することで(cronジョブやWindowsタスクスケジューラを使用)、予防的な警告が得られます。台帳を使用しているため、追加したばかりの取引を含む_すべての_取引を考慮できます。
支払い期限の到来
Beancountで請求書や期限を追跡している場合、将来の支払いをマークし、スクリプトでリマインダーを作成できます。Beancountで将来の義務を表す2つの方法:
-
イベント: Beancountは任意の日付付きメモ用の
eventディレクティブをサポートしています。たとえば:2025-05-10 event "BillDue" "Mortgage payment due"これは残高には影響しませんが、日付とラベルを記録します。スクリプトは
entriesをスキャンしてEvent.type == "BillDue"(または選択したカスタムタイプ)のEventエントリを探し、日付が今日から7日以内かどうかを確認できます。該当する場合はアラート(メール、通知、ポップアップなど)をトリガーします。 -
将来の取引: 一部の人は、スケジュールされた支払いなどのために将来日付の取引(後付け)を入力します。これらは日付が過ぎるまで残高に表示されません(将来日付でレポートを実行しない限り)。スクリプトは近い将来の日付の取引を探してリスト化できます。
これらを使用して、「チクル」スクリプトを作成できます。実行すると、間もなく期限が来るタスクや請求書のリストを出力します。Google CalendarやタスクマネージャーのようなAPIと統合して、自動的にリマインダーを作成することもできます。
異常検知
既知のしきい値や日付以外にも、異常なパターンのカスタムアラートをスクリプト化できます。たとえば、通常は毎月発生する支出が発生していない場合(請求書の支払い忘れの可能性)、または今月のカテゴリ支出が異常に高い場合、スクリプトでフラグを立てられます。これは通常、最近のデータをクエリし、履歴と比較することを含みます(統計やMLを使用する高度なトピックかもしれません)。
実際には、多くのユーザーは調整(予期しない取引の捕捉)に依存して異常を検出しています。銀行の通知(取引ごとのメールなど)を受け取る場合、スクリプトで解析して自動的にBeancountに追加するか、少なくとも記録されていることを確認できます。ある愛好家は、銀行に取引アラートメールを送信するよう設定し、それを解析して台帳に自動的に追加する計画を立てていました。この種のイベント駆動型アラートにより、記録されない取引なしを確保できます。
カスタムプラグインとビューでFavaを拡張する
Favaは拡張システムを通じてすでにスクリプト可能です。自動化やレポートをWebインターフェースに直接統合したい場合は、PythonでFava拡張機能(プラグインとも呼ばれる)を書くことができます。
Fava拡張機能の仕組み: 拡張機能は、fava.ext.FavaExtensionBaseを継承するクラスを定義するPythonモジュールです。Beancountファイルのカスタムオプションで登録します。たとえば、myextension.pyファイルにMyAlerts(FavaExtensionBase)クラスがある場合、台帳に以下を追加して有効化できます:
1970-01-01 custom "fava-extension" "myextension"Favaが読み込まれると、そのモジュールをインポートしてMyAlertsクラスを初期化します。
拡張機能はいくつかのことができます:
- フック: Favaのライフサイクルのイベントにフックできます。たとえば、
after_load_file()は台帳が読み込まれた後に呼び出されます。これを使用してチェックを実行したり、データを事前計算したりできます。低残高チェックをFava_内で_実装したい場合、after_load_fileで口座残高を反復処理し、警告を保存できます(ただし、UIに表示するには、FavaAPIErrorを発生させるかJavascriptで通知を表示するなど、もう少し作業が必要かもしれません)。 - カスタムレポート/ページ: 拡張クラスが
report_title属性を設定すると、Favaはサイドバーに新しいページを追加します。そのページのコンテンツ用にテンプレート(HTML/Jinja2)を提供します。これが、Favaがデフォルトで持っていないダッシュボードやサマリーなど、完全に新しいビューを作成する方法です。拡張機能は必要なデータを収集でき(self.ledgerにすべてのエントリ、残高などが含まれます)、テンプレートをレンダリングします。
たとえば、Favaの組み込みportfolio_list拡張機能は、ポートフォリオのポジションをリストするページを追加します。コミュニティ拡張機能はさらに進んでいます:
- ダッシュボード: fava-dashboardsプラグインは、カスタムチャートとパネル(Apache EChartsなどのライブラリを使用)を定義できます。実行するクエリのYAML設定を読み取り、Beancountを通じて実行し、Favaに動的ダッシュボードページを生成します。本質的に、BeancountデータとJavaScriptチャートライブラリを結びつけて、インタラクティブな可視化を生成します。
- ポートフォリオ分析: PortfolioSummary拡張機能(ユーザー投稿)は、投資サマリー(勘定科目のグループ化、IRRの計算など)を計算し、FavaのUIに表示します。
- 取引レビュー: 別の拡張機能fava-reviewは、時間経過による取引のレビュー(たとえば、領収書を見逃していないか確認)を支援します。
自分でシンプルな拡張機能を作成するには、FavaExtensionBaseをサブクラス化します。たとえば、ページを追加する最小限の拡張機能は次のようになります:
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")これをhello.pyに配置し、台帳にcustom "fava-extension" "hello"を追加すると、Favaに新しい「Hello World」ページが表示されます(ページコンテンツを定義するにはtemplatesサブフォルダーにHelloReport.htmlテンプレートファイルも必要ですが、フックのみを使用する場合は不要です)。テンプレートは拡張クラスに添付したデータを使用できます。FavaはJinja2テンプレートを使用するため、そのテンプレートでデータをHTMLテーブルやチャートにレンダリングできます。
注意: Favaの拡張システムは強力ですが、「不安定」(変更される可能性がある)と見なされています。カスタムページを作成するには、Web開発(HTML/JS)にある程度の知識が必要です。スクリプトや分析を実行するだけが目的なら、それらを外部スクリプトとして維持する方が簡単かもしれません。ワークフローに合わせたアプリ内エクスペリエンスが必要な場合は、Fava拡張機能を使用してください。
サードパーティのAPIとデータの統合
スクリプト可能なワークフローの利点の1つは、外部データを取り込めることです。一般的な統合は次のとおりです:
-
為替レートとコモディティ: Beancountは設計上、価格を自動取得しません(レポートの決定性を保つため)が、レートを供給するための_Price_ディレクティブを提供します。これらの価格の取得を自動化できます。たとえば、スクリプトでAPI(Yahoo Finance、Alpha Vantageなど)から最新の為替レートや株価を取得し、台帳に価格エントリを追加できます:
2025-04-30 price BTC 30000 USD 2025-04-30 price EUR 1.10 USD管理エンジンのBeanpriceをバックエンドにした
bea priceのようなツールがあり、毎日の引用を取得してBeancount形式で出力します。一度bea engine enable beanpriceで有効化し、毎晩bea price main.beancountをスケジュールしてprices.beancountインクルードファイルを更新できます。またはPythonを使用します:たとえば、requestsライブラリでAPIを呼び出します。_Beancountのドキュメントでは、公開取引資産について「価格をダウンロードしてディレクティブを書き出すコードを呼び出せる」_と示唆しています。つまり、手動でprice行を書くのではなく、スクリプトにルックアップと挿入を任せます。 -
株式ポートフォリオデータ: 為替レートと同様に、APIと統合して詳細な株式データや配当を取得できます。たとえば、Yahoo Finance API(またはコミュニティライブラリの
yfinance)はティッカーシンボルの履歴データを取得できます。スクリプトで保有する各株式の月次価格履歴を台帳に更新し、正確な履歴レポートの時価評価を可能にします。一部のカスタム拡張機能(_fava_investor_など)は表示用に価格データを動的に取得しますが、最も簡単なのは定期的に台帳に価格をインポートすることです。 -
バンキングAPI(Open Banking/Plaid): CSVをダウンロードする代わりに、APIを使用して取引を自動取得できます。Plaidなどのサービスは銀行口座を集約し、取引へのプログラム的なアクセスを提供します。高度な設定では、PlaidのAPIを使用して毎日新しい取引を取得し、ファイルに保存(または直接台帳にインポート)するPythonスクリプトを作成できます。あるパワーユーザーは、Plaidをインポートパイプラインにフィードし、簿記をほぼ自動化するシステムを構築しました。彼らは「Plaid APIにサインアップしてローカルで同じことをすることを妨げるものは何もない」と述べています。つまり、銀行データを取得するローカルスクリプトを書き、Beancountのインポーターロジックを使用して台帳エントリに解析できます。一部の地域では銀行が提供するオープンバンキングAPIがあり、同様に使用できます。
-
その他のAPI: 予算ツール(計画予算をエクスポートしてBeancountの実績と比較)や、OCR APIを使用して領収書を読み取り、取引に自動マッチングすることもできます。スクリプトはPythonエコシステムに完全にアクセスできるため、アラート送信用のメールサービスから、月次財務メトリクスでスプレッドシートを更新するGoogle Sheets、Telegramボットでサマリーレポートを送信するメッセージングアプリまで、あらゆるものを統合できます。
サードパーティAPIを使用する場合、資格情報を保護し(APIキーには環境変数や設定ファイルを使用)、スクリプトでエラー(ネットワーク問題、APIダウンタイム)を適切に処理することを忘れないでください。データをキャッシュすることも賢明です(たとえば、取得した為替レートを保存して、同じ履歴レートを繰り返し要求しないように)。
モジュール化され、維持可能なスクリプトのベストプラクティス
スクリプト可能なワークフローを構築する際は、コードを整理し、堅牢に保ちましょう:
-
モジュール性: 異なる関心事を異なるスクリプトやモジュールに分割します。たとえば、「データインポート/調整」と「レポート生成」と「アラート」の別々のスクリプトを作成します。台帳用の小さなPythonパッケージを作成し、
ledger_import.py、ledger_reports.pyなどのモジュールを持つこともできます。これにより、各部分が理解しやすく、テストしやすくなります。 -
設定: 値をハードコーディングしないでください。口座名、しきい値、APIキー、日付範囲などには、設定ファイルまたはスクリプト先頭の変数を使用します。これにより、コードを深く編集せずに調整できます。たとえば、
LOW_BALANCE_THRESHOLDS = {"Assets:Bank:Checking": 500, "Assets:Savings": 1000}を先頭に定義し、アラートスクリプトはこの辞書をループ処理できます。 -
テスト: 財務自動化をミッションクリティカルなコードとして扱ってください—実際にそうだからです!複雑なロジックにはテストを書きましょう。Beancountには(インポーターテスト用に内部的に使用される)テストヘルパーがあり、台帳入力をシミュレートするために利用できます。派手なフレームワークがなくても、ダミーCSVと期待される出力取引を持ち、インポートスクリプトが正しいエントリを生成することをアサートできます。
pytestを使用している場合は、簡単に統合できます(Alex Wattがjust testコマンドでpytestをラップして行ったように)。 -
バージョン管理: 台帳とスクリプトをバージョン管理(git)下に置きます。これはバックアップと履歴を提供するだけでなく、管理された方法で変更を加えることを促します。「金融スクリプト」のリリースにタグを付けたり、問題のデバッグ時に差分を確認したりできます。一部のユーザーは金融記録をGitで追跡して、時間経過による変化を確認しています。ただし、リポジトリ内の機密データ(生の明細ファイルやAPIキーなど)を無視するように注意してください。
-
ドキュメント: カスタムワークフローを将来の自分用に文書化します。リポジトリ内のREADMEで、環境のセットアップ方法、各スクリプトの実行方法、それぞれの機能を説明すると、数か月後には非常に価値があります。また、特に明白でない会計ロジックやAPIインタラクションにはコードにコメントを付けましょう。
-
Favaプラグインのメンテナンス: Fava拡張機能を書く場合は、シンプルに保ちましょう。Favaは変更される可能性があるため、機能を絞った小さな拡張機能の方が更新しやすいです。ロジックを重複させないようにしてください。ハードコーディングされた計算は台帳の変更に敏感になる可能性があるため、可能な限りBeancountのクエリエンジンや既存のヘルパー関数を使用してください。
-
セキュリティ: スクリプトは機密データを扱い、外部サービスに接続する可能性があるため、注意して扱ってください。APIキーを公開せず、自動化を安全なマシンで実行することを検討してください。ホスト型ソリューションやクラウド(GitHub ActionsのスケジュールやサーバーでのFava実行など)を使用する場合は、台帳データが保存時に暗号化されていること、プライバシーへの影響を理解していることを確認してください。
これらのプラクティスに従うことで、金融が(ツール自体も)進化してもワークフローが信頼性を維持できます。毎年、最小限の調整で再利用できるスクリプトが必要です。
結論
BeancountとFavaは、テクノロジーに精通したユーザーがパーソナルファイナンスの追跡を完全にカスタマイズするための、強力で柔軟なプラットフォームを提供します。Pythonスクリプトを書くことで、明細の調整などの退屈なタスクを自動化し、ニーズに合わせたリッチなレポートを生成し、タイムリーなアラートで財務を常に把握できます。基本から高度な例まで(シンプルなクエリやCSVインポートから、本格的なFavaプラグインや外部API統合まで)をカバーしました。実装する際は、シンプルに始めて徐々に構築してください。ほんの数個の小さな自動化スクリプトでも、何時間もの作業を節約し、正確性を大幅に向上させることができます。すべてがプレーンテキストとPythonであるため、あなたが完全に制御できることを忘れないでください—あなたの金融システムはあなたとともに成長し、特定のニーズに合わせて曲がります。ハッピースクリプティング!
出典: 上記のテクニックはBeancountのドキュメントとコミュニティの経験から得られています。詳細については、Beancountの公式ドキュメント、コミュニティガイドとブログ、便利なプラグインとツールへのリンクがあるAwesome Beancountリポジトリを参照してください。