Beancount 示例与教程

Martin Blais,2014 年 10 月

http://furius.ca/beancount/doc/example

示例文件生成器

转换为 Ledger 输入格式

示例用户档案

未来新增功能

教程

生成示例文件

生成报表

生成余额

生成资产负债表和损益表

日记账

持仓

其他报告

其他格式

通过网页界面查看报告

Beancount 报告的未来

示例文件生成器

Beancount 提供了一个命令,可生成几年真实的用户历史记录:

bean-example > example.beancount

该脚本会检查生成的输出是否能被 Beancount 正常处理(如果失败,请重试或联系作者 blais@furius.ca)。请注意,有一个选项可用于固定随机生成器的种子以生成记录。

您可以为该用户生成多年账本数据;有关可用选项,请参阅

bean-example --help

该脚本的目的包括:

  • 为用户提供一个真实的匿名数据集,以便实验、测试 Beancount、生成报表等。

  • 与 Ledger 生成的报表进行比较。

  • 作为本教程中使用的示例文件。

  • 作为对 Beancount 进行压力测试的输入。

转换为 Ledger 输入格式

应可将脚本生成的示例文件转换为 Ledger 语法,如下所示:

bean-report example.beancount ledger > example.lgr

如果在转换过程中遇到任何问题,请告知我。虽然我已设置自动化测试以确保转换成功,但我主要精力集中在 Beancount 本身,仅偶尔使用 Ledger 进行比较或在邮件列表中演示某些内容。

示例用户档案

以下是该用户的高层次概况。在以下文本中,为简便起见,我将使用男性代词“他”。

  • 他居住在美国某地,使用单一的法定货币:“美元”。他租住一套公寓。

  • 收入:他是一名软件工程师(抱歉我忍不住这么写),从一家软件公司获得 modest 的薪资收入。

    • 他每两周领取一次工资。

    • 他最大限度地向公司的 401k 计划供款,公司会匹配他的供款。

    • 他的工资通过直接存款方式存入他的支票账户。

    • 他享受并支付由雇主提供的健康保险计划的保费。

    • 他明确记录自己的休假时数。

  • 支出

    • 支票账户:他通过支票支付公寓租金,同时直接从支票账户支付电费、互联网服务提供商费用和手机账单。他的银行每月还会收取一笔手续费。

    • 信用卡:他还有一些其他常规支出,例如杂货和与朋友外出就餐,这些费用通过信用卡支付。

  • 资产

    • 银行账户:他在一家大型美国银行拥有账户。

    • 退休账户:他的 401k 账户托管在富达或先锋,并全部投资于两只基金——股票和债券的组合。该账户内从未发生过卖出操作。该账户按平均成本法记账。

    • 其他投资:他能额外储蓄的资金会从支票账户转入应税投资账户,用于购买股票和 ETF 的组合,偶尔也会进行卖出并实现收益。

  • 负债

    • 信用卡:他拥有一到两张由另一家银行发行的信用卡。
  • 事件/标签:他每年会进行一到两次短期度假,去一些有趣的地方旅行。

未来新增功能

请注意,随着我增强示例生成脚本,此用户画像的复杂性将逐步提升。如果您希望在示例文件中看到来自配方手册或其他特定场景,请告知我(提交补丁是最佳方式)。

  • 根据选项生成虚假的 PDF 文档文件,并为它们添加相应的文档指令,其中大部分为隐式,部分为显式。

  • 生成更多支出:

    • 一些真实的现金支出。

    • 添加一辆车:包括汽车维修、汽油等费用。移除有轨电车示例,因其过于城市化。

    • 添加慈善捐赠。

    • 添加第二张信用卡,并多样化支出来源。

  • 为链接添加真实用途,例如 401k 匹配:雇主的供款应与员工的供款建立关联。或其他类似场景。

  • 生成一笔学生贷款及其还款记录。大额负债是常见情况,我希望即使不是房贷,也能体现这一点。

  • 将退休账户转换为按平均成本法记账,并添加相应费用,这些费用若使用明确批次将无法追踪。

  • 根据配方手册添加医疗支出的追踪。

  • 添加其他货币的外部账户以及该货币的交易和转账。

教程

本节提供了一些使用 Beancount 生成报告的基本示例,这些示例基于其典型输出文件。此处列出的报告并非详尽无遗。

您可以跟随本教程生成自己的示例文件,或直接查看 beancount/examples/tutorial 中的文件(如果您更喜欢这种方式)。

生成示例文件

首先生成示例文件:

bean-example > example.beancount

打开 example.beancount 并查看其内容。

接下来,在开始生成报告之前,请验证文件能否无错误加载:

bean-check example.beancount

它应静默返回,不输出任何内容(bean-check 仅在存在错误时输出信息,成功时则不输出任何内容)。

生成报告

让我们生成所有账户最终余额的报告 [输出]

bean-report example.beancount balances

如您所见,bean-report 脚本包含用于生成各种报告的子命令。要列出可用的报告,请使用 --help-reports [输出]

bean-report --help-reports

要查看特定报告的可用选项,请对该报告使用 --help [输出]

bean-report example.beancount balances --help

每个报告类型的特定选项各不相同。

您也可以列出脚本的全局选项 [输出]

bean-report --help

全局选项允许您指定报告的输出格式。要查看每种报告支持的格式,请使用 --help-formats [输出]

bean-report --help-formats

生成余额

很好,现在我们知道如何生成所有账户的余额报告了。不过这个账户列表相当详细。让我们仅限制输出为我们关心的账户 [输出]

bean-report example.beancount balances -e ETrade

在这里您可以查看每个投资子账户持有的单位数量。要显示成本,请使用 --cost 选项 [输出]

bean-report example.beancount balances -e ETrade --cost

格式化工具

有时将账户的层次结构列表以树形方式呈现会更直观。您可以使用 Beancount 提供的 “treeify” 工具来实现:

bean-report example.beancount balances | treeify

此工具适用于任何看起来像账户名称列的数据列(您也可以配置它处理文件名或其他模式)。

生成资产负债表和损益表

让我们生成一份资产负债表:

bean-report example.beancount balsheet

遗憾的是,目前仅支持 HTML 格式输出。此外,命令行上不支持过滤资产负债表条目。请将其输出到文件并用浏览器打开 [输出]

bean-report example.beancount balsheet > /tmp/balsheet.html

您也可以对损益表执行相同操作:

bean-report example.beancount income > /tmp/income.html

日记账

您还可以生成日记账(在 Ledger 中称为“寄存器”)。例如,查看支票账户的交易记录 [输出]

bean-report example.beancount journal -a Assets:US:BofA:Checking

要显示累计余额列,请添加 --balance 选项 [输出]

bean-report example.beancount journal -a Assets:US:BofA:Checking --balance

库存以持有的单位数量显示[输出]

bean-report example.beancount journal -a Assets:US:ETrade:GLD

若要按成本价显示数值,请使用 --cost 选项[输出]

bean-report example.beancount journal -a Assets:US:ETrade:GLD --cost

要显示日记账,通常需要限制您想查看的记账条目。如果不做限制,记账条目将不会显示任何变化,因为所有交易的借贷方都会被计入累计余额,总和为零。但即便如此,仍可尝试一下[输出]

bean-report example.beancount journal --balance

持仓

获取持仓总列表的聚合方式有多种。列出详细持仓[输出]

bean-report example.beancount holdings

按账户聚合持仓,请执行以下操作[输出]

bean-report example.beancount holdings --by=account

由于通常的做法是为实际账户中持有的每种商品创建并使用一个专用的 Beancount 子账户名称,因此我们可以进一步细化,将这些子账户聚合到其父账户(即“根”账户)[输出]

bean-report example.beancount holdings --by=root-account

我们可以按商品聚合[输出]

bean-report example.beancount holdings --by=commodity

或按商品报价的货币聚合,这能帮助我们了解自身的货币风险敞口[输出]

bean-report example.beancount holdings --by=currency

最后,我们可以将所有持仓汇总以计算净资产[输出]

bean-report example.beancount networth

还有其他几种将金额转换为统一货币的选项。详情请参阅帮助。

其他报表

还有许多其他杂项报表可供使用。尝试其中几个。

列出所有账户[输出]

bean-report example.beancount accounts

列出事件[输出]

bean-report example.beancount events

按类型统计指令数量[输出]

bean-report example.beancount stats-directives

按类型统计记账条目数量[输出]

bean-report example.beancount stats-postings

其他格式

报表可能支持多种输出格式。您可以通过 --format (-f) 全局选项更改输出格式[输出]

bean-report -f csv example.beancount holdings

请注意,“beancount”和“ledger”是有效的输出格式:它们分别指 Beancount 和 Ledger 的输入语法。

通过网页界面查看报表

Fava 是一个独立项目,为本地机器上的 Beancount 提供网页界面。请查看此处的演示。Fava 的GitHub 页面 介绍了如何安装和使用它。Fava 会显示您的账户树、余额和损益表、日记账和持仓,并允许直接在其网页界面中运行 Beancount 查询。Fava 还提供针对特殊需求的插件。

注意:如果您正在寻找随 Beancount 一起发布的 bean-web 网络服务器,它现已弃用。Fava 是推荐的网页界面。

Beancount 报表的未来

从可定制性的角度来看,我发现上面的命令行报告相当令人不满意,这让我非常困扰。主要原因是我一直对 Beancount 网页界面的功能感到满意和安心。随着我越来越多地使用命令行界面,我越来越希望有一种更明确、更规范的方式,来应用网页界面中所有可用的筛选条件,甚至更多功能。因此,我目前正在实现一种类似 SQL 的查询语言。这种语法将使我能够移除上述所有自定义报告,并用一种统一一致的查询语法取而代之。这项工作正在进行中。

所有的持仓报告,甚至其内部对象,也将被这种类似 SQL 的查询语法所取代。持仓无需单独处理:它们本质上只是某一特定时间点可用的头寸列表,配合查询语法中的合适访问器以及对多个列的聚合支持,我们应当能够等效地生成所有这些报告,并简化代码。

—— Martin Blais,2014 年 10 月