Skip to content

Beancount言語構文

Beancount言語の構文をまとめるが、網羅するのではなく覚えておいたほうが良いことだけを抜粋する。公式ドキュメントはBeancount Language Syntaxにある。

Beancountはファイルを読み込んだ後で、特定の順番にソートするので、日付が前後していても問題ない。ただしこれに関連して、ソートの順序には特徴があるので以下に同日で優先度が高い(早く処理される)順に並べる。

  1. open
  2. balance
  3. これら以外のディレクティブ
  4. txn
  5. close

これはbeancount/core/data.py:695,705で書かれているコメントを参照した。

open ディレクティブでBeancountの勘定科目を設定する。日本の場合はあらかじめ決まった勘定科目しか使えないらしいが、Beancountではルートの項目以外はなんでもいい様子。

txn ディレクティブで取引の記録を記述する。txn は省略可能なので、一般的にはフラグを使って txn は省略することが多い。

2024-10-15 ! "ツクモex" "PCパーツ"
Liabilities:Amex:CreditCard 45,000 JPY
Expenses:Shopping 45,000 JPY
2024-10-18 * "リバティ長岡" "食材"
Expenses:Food:Groceries 1,300 JPY
Assets:Cash -1,300 JPY

これを一般化すると次のようなルールとなる。

YYYY-MM-DD [txn|Flags] [[Payee] Narrattion]
[[key: value] ...]
[Flags] Account Amount

トランザクションの各行にはメタデータで id を与えられるらしいので、インポートした場合に重複があるかどうかの判定はこれを使うといいのだろう。

原価は {} で指示するらしいが、たぶん使わない。以下の例は「1つあたり4,000円で買ったETHを、1つあたり5,000円で5つ処理」となるらしい。

5.0 ETH { 4,000 JPY } @ 5,000 JPY

取引記録では価格(Amount)が必須となっている。Amount の構文ではひとつの数値を書くだけではなく演算も行える。

2,996 - 221 JPY

通貨の両替を伴う場合は @ を使って「支払った通貨1ユニット」の金額(Price)を与えたり、@@ で「支払った価格の合計」金額(Cost)を与えることも可能になっている。具体的な例でいえば、GitHubはUSドルで請求してくるけれども、クレジットカード会社からは日本円で引き落としが行われるので為替の変換が必要になるので @@ を使えそうな気がする。

4.40 USD @@ 740 JPY
4.40 USD @ 168.18 JPY

なんだけど、内部的に @@@ と解釈されるようで、4.40 USD @@ 740 JPY とすると 4.40 USD @ 168.1818.. と扱われ、これを計算すると合計金額は $739.999$ なので確かにバランスしない。Beancount における精度と許容誤差のガイドによると、端数は金額の有効桁数の半分(1.0なら1.05)までは有効で、端数を明示的に指示するオプションもあるが、上記の例では効果がなかった。

option "inferred_tolerance_default" "JPY:0.5"
option "inferred_tolerance_default" "USD:0.005"
option "tolerance_multiplier" "1.1"

implicit_prices プラグインも入れてみたけれど、意味がなかった。これはFlatpak付属の beancount に入っていないだけかもしれない。

plugin "beancount.plugins.implicit_prices"

返金など、関連するトランザクションをまとめるリンクという機能がある。

2026-07-01 * "Amazon" "購入" ^amazon-refund-2026
Expenses:Toys 4,000 JPY
Liabilities:CreditCard
2026-07-01 * "Amazon" "返金" ^amazon-refund-2026
Expenses:Toys -4,000 JPY
Liabilities:CreditCard

似たような機能でタグもある。

2026-07-01 * "交通費" #trip-wakayama-2026

一連のトランザクションをまとめてタグ付けする場合は pushtagpoptag で囲む。これらのディレクティブに日付は必要ない。

pushtag #trip-wakayama-2026
2026-07-01 * "交通費"
...
2026-07-01 * "宿泊費"
...
poptag #trip-wakayama-2026

txn の他にもいくつかあるが、主に使うのはこの辺り。

  • balance
  • pad
  • price

padbalance と合わせて使う。pad 直後に balance があれば、その値で埋めるらしい。ただし pad記述した日付に 埋め合わせるための金額を txn で生成するので、balance と同じ日付にすると