复式借贷记账法 Beancount (1) - 基础知识

9 minute read

本文介绍一些基本概念,推荐仔细阅读References. 然后就是 bean-example > example.beancoun 其实也非常具有参考价值。

基本概念

商品单位 Commodities

与其说是我们狭义理解的商品,应该说理解为广义的商品,即具有交换价值的东西。 这里定义的通常是账户的单位。它可以是货币单位,也可以是某一种资产的单位,比如汽车,房子等。

账户 Accounts

账户详情
Asset 资产有形或者无形的资产,比如 现金, 银行账户, 有价证券, 车子,房子 等等
Liabilities 负债各种形式的负债,房贷,车贷,信用卡债,花呗
Income 收入工资,奖金,彩票中奖,出租屋收入,股息,存款利息,借贷利息 等等
Expenses 支出各种花费,手续费,购物,旅行,支付的贷款利息等等
Equity 权益记录账本初始化之前的净收入(income - expenses)

前面四种账户的类型应该很好理解,可能就是权益类型的账户比较难以理解一些。

The account type “equity” is used for accounts that hold a summary of the net income implied by all the past activity.

所以权益账户的目的就是帮助 zero-out 你所有的账户,使得以下恒等式成立

$$ income + liabilities + assets + expenses + equity = 0 $$

权益账户的用处有

  • 初始化账本时已有的数据

其他情况下, 应该可以等价转换为Assets/Libabilities

基本语法

YYYY-MM-DD <操作> <参数...>

创建商品单位

1998-07-22 commodity AAPL
  name: "Apple Computer Inc."

对商品定价

2015-04-30 price AAPL   125.15 USD
2015-05-30 price AAPL   130.28 USD

创建和关闭账户

账户需要显式的创建, 这里的关键字是open, 当现实中账户关闭的时候,也可以关闭 close 。账户命名是 colon-separated tags,一系列的标签,通过冒号连接起来。虽然没有特定的规范,但是在GUI上会以这样的树形结构来聚合账户上的余额,所以一般会利用标签来逐渐缩小范围。

比如

2002-01-17 open Assets:Cash USD
2002-01-17 open Equity:Open-Balances


2002-01-17 open Liabilities:CreditCard:US:Chase:Freedom

2020-01-17 close Liabilities:CreditCard:US:Chase:Freedom

交易

2014-05-05 txn "Cafe Mogador" "Lamb tagine with wine"
  Liabilities:CreditCard:CapitalOne         -37.45 USD
  Expenses:Restaurant

2014-03-19 * "Acme Corp" "Bi-monthly salary payment"
  Assets:MyBank:Checking             3062.68 USD     ; Direct deposit
  Income:AcmeCorp:Salary            -4615.38 USD     ; Gross salary
  Expenses:Taxes:TY2014:Federal       920.53 USD     ; Federal taxes
  Expenses:Taxes:TY2014:SocSec        286.15 USD     ; Social security
  Expenses:Taxes:TY2014:Medicare       66.92 USD     ; Medicare
  Expenses:Taxes:TY2014:StateNY       277.90 USD     ; New York taxes
  Expenses:Taxes:TY2014:SDI             1.20 USD     ; Disability insurance

通用格式

YYYY-MM-DD [txn|Flag] [[Payee] Narration]
   [Key: Value] ; meta datas
   ...
   ...
   [Flag] Account Amount [{Cost}] [@ Price] ; posting
   ...
   ...
   ...

通常交易的directives是txn 但是因为这个是beancount里最常见的记录,因此允许用户省略 通常 * 表示交易数据无误,而!表示交易数据可能有错。

* 后的两个string,第一个是payee,就是收款方, 可选的,也可以省略 第二个是narration 就是描述,

从第二行起,可以加入metadata meta data完了之后是 交易的数据(postings) 可以是很多条,这也是复式记账的好处,可以完整的描述钱的去向,比如上面的例子中,工资的发放就涉及到了很多账户。

在Posting中可以记录价格,和货币转换

2012-11-03 * "Transfer to account in Canada"
  Assets:MyBank:Checking            -400.00 USD @ 1.09 CAD
  Assets:FR:SocGen:Checking          436.01 CAD

这里一个 @ 表示的是单价,如果用 @@则表示的是总成本

2012-11-03 * "Transfer to account in Canada"
  Assets:MyBank:Checking            -400.00 USD @@ 436.01 CAD
  Assets:FR:SocGen:Checking          436.01 CAD

断言 Balance Assertion

编程的同学应该很容易理解. 这个概念和测试中的断言是一个意思。

当你对某一个账户在某个时间点上做断言的时候,

2015-06-01 balance Liabilities:CreditCard  -634.30 USD

Beancount会根据这个来验证其账目的正确性,如果不匹配,则会报错。这个时候就需要对账找出并且修复错误。显然,时不时的对账户做断言是保持账户正确性的必要条件。而且如果出错,你只需要对比上一次正确断言和当前出错断言之间的记录即可。

填充 Padding

填充是和断言一起使用的,当balance assertion出现在pad之后(二者时间之内不能有其他交易),beancount会自动根据pad的参数,将余额调整至断言中的数据。

2019-12-31 pad Liabilities:CreditCard:US:Chase:SapphirePreferred  Equity:Opening-Balances
2020-01-01 balance Liabilities:CreditCard:US:Chase:SapphirePreferred      -95.0 USD

这个在初始化账本的时候,需要设定账户初始值的时候会频繁使用。

项目结构

Beancount的项目其实就是一堆beancount文件。 由于有include 关键字的存在,其项目结构是可以很松散的。

我的建议是合理的利用文件夹和include来管理beancount项目。

folder structure

以我个人的经验,首先有一个main.beancount 作为入口文件。 里面并没有任何交易记录,只做一些全局变量的定义,比如Assets,Equity,货币单位。 然后利用 include 去索引其他文件夹

include "income/_index.beancount"
include "expense/_index.beancount"
include "property/_index.beancount"
include "vehicle/_index.beancount"
include "investment/_index.beancount"

这里我利用_index.beancount来做文件的索引,每一个文件夹相当于一个scope 就会有一个index文件。这个index位于每一个文件夹下,确保每一个数据文件都被include进来,同时我也在index文件中定义在这个scope里需要的账户。

至于如何分文件夹,则是一个千人千面的问题了。 由于我大部分的账目都是信用卡,然后银行卡多数是付信用卡账单。这些都可以自动化导入,所以我利用年份命名的文件来记录这些流水。 这里面的大部分去想都是expense。但是因为比较杂所以不好归纳到单个文件。 至于expense文件夹下,我只放置一些周期性的支出,比如手机账单,水电气账单,车险房险等。 车贷房贷都是单独track,所以各放入了一个文件夹。 收入里面则按照公司,每一个公司一个beancount文件。

参考文献

系列介绍

准备用一个系列的文章来介绍这个工具和一些技巧。 这些技巧有一些是我从已有的模版中找出来,也有一些是在Google Group里看到大家的推荐,自己又尝试出来的方法。

  1. 先导
  2. 基础知识
  3. 环境设置
  4. 如何对房产建模
  5. 如何对RSU建模
  6. 如何对ESPP建模
  7. 自动化导入
  8. 安全

wechat-qrcode