记账软件(三)复式记账篇

现有流水式记账中遇到的问题

  1. 存在记错记漏的情况,经常需要手动强制平帐。
  2. 数据的安全性,随着记账内容的增多,会暴露更多的用户隐私。
  3. 手机记账大多数打开都有几秒钟的广告,影响使用体验。
  4. 使用随手记这类的软件需要一天大量的打开来避免记漏,过于繁琐。
  5. 不支持管理加密资产,更不支持自动同步加密货币的汇率。
  6. 单笔支出多种类支付的记账问题。如果分开记,那么信用卡的消费记录和实际不符,对账时会造成干扰;如果一并记,那这支出应该归到哪个类别?
  7. 基金购买后的收益和损失无法正确的记录,只能在资产变动幅度较大时添加一次总的更正。投资收益与投资亏损混合在投资账户中,投资了一年连自己亏了赚了多少钱都不知道
  8. 不支持分摊,购买分期付款的产品,费用全部记入了当月,实际为3个月或12个月的支出。
  9. 一个月左右就必然会遇到帐目不准确的问题,可能是支出帐号错误,可能是信用卡有返利,可能是银行卡有利息,每次都需要手动调整。
  10. 报销繁琐,不知道能报销多少钱,也不知道那些是报销过的。

Beancount

文章摘要

实际上,要想学会基础的复式记账,就得理解完整的五个项目,项目如下:

1
2
3
4
5
Assets(资产)
Liabilities(负债)
Expenses(费用)
Income(收入)
Equity(权益)

Assets 就是你的个人资产,可以是银行卡、现金、基金、股票等;Liabilities
简单理解就是借呗、卡贷、房贷、车贷这些等;Expenses 就是各类消费/开销;Income
就是资产来源,如工资、基金收益、股票收益等;Equity 就是你原本就有的资产或者每个月除去 Liabilities 和 Expenses
后剩下的 Assets 。具体每项如何使用,我在下方会结合软件进行介绍。

此外,这五个项目的关系如下 :

1
(Income + Liabilities) + (Assets + Expenses) + Equity = 0

  • 把收入(Income)想像成一个装着你一生(过去和未来)所有劳动成果的桶,每次你的收入都是从桶里取出东西(通常以货币的形式),一直取啊取啊,直到某一天……所以收入桶的数字通常是负数
  • 把费用(Expenses)想像成一个装着你一生(过去和未来)所有消费的桶,每次你的支出都是往桶里放东西(以货币的形式表现),和朋友出去唱歌转换成快乐存进去,看过的电子书转换成精神食粮存进去,吃过的饭转换成……所以费用桶的数字通常是正数

一旦接受了「收入和负债通常为负数」、「资产和费用通常为正数」这两个设定,那你便很容易理解这条等式了:

(Income + Liabilities) + (Assets + Expenses) + Equity = 0

用大白话来说就是:你赚的钱(Income),加上你借来的钱(Liabilities),最终要么变成你自己的钱(Assets),要么就是花掉了(Expenses),最终得到的是个零。这就是人的一辈子……

等下,Equity 是怎么来的?仔细想想小明的例子,他的四个桶要满足这个等式,前提是桶里都是空的。但是小明不是一个刚出生的婴儿,他已经活了二十多年了,之前的
Income、Liabilities、Assets、Expenses 怎么算呢?答案就是放到 Equity 里。当小明决定开始用复式簿记的时候,他从 Equity 里倒一些豆子其他桶里(或从其他桶倒一些豆子到 Equity 里),将其他桶的数字调节成符合当前实际情况即可。实际操作中,人们一般只关心 Income 和 Expenses 桶的数字在某段时间内的变化,并不关心它的总数(除非你想统计你出生到现在一共收入多少、支出多少),只要把 Assets 和 Liabilities调节准就行了。这便是 Equity 的作用——存放已有的「权益」。

更一般地,Equity 可以用来存放所选取的时间范围之前的「汇总」。比如小明从 2012 年开始用 Beancount,一直用到 2016年,他想只看 2016 年的财务状况,那 Beancount 便会把他 2016 之前四年的数据「调节」到 Equity 里,来维持 2016年会计恒等式的平衡。


在 Beancount 中通过 balance 实现账户核对。

假设在 10 月 17 日 24 点,尾号 1234 的银行卡余额为 5000 元,记录如下:

1
2019-10-18 balance Assets:Card:1234   5000.00 CNY

Beancount 会自动汇总 10 月 17 日(含)以前尾号 1234 的银行卡所有收支,如果历史交易记录无误,那么计算出来也应该是 5000 元。若不是 5000 元,则 Beancount 报错,表示历史交易记录有误。


虚拟货币记账

在使用美元买进虚拟货币的时候,可以用 {} 表示每一币的持有成本,并用 @@ 表示买入总价。

1
2
3
4
5
2017-06-01 * "Coinbase" "BTC"
Assets:Crypto:Coinbase:Wallet +0.03000000 BTC {3000.00 USD} @@ 90 USD
Expenses:Crypto:Commissions +3.00 USD
Liabilities:US:Chase:Freedom -93.00 USD

而卖出的时候,由于我对这个钱包采用的是先进先出 (FIFO) 的模式,可以不指明卖出比特币的持有成本,这样 Beancount 会直接以最早买入的比特币的持有成本来计算盈余。卖出时可以用 @ 表示卖出时每币的价格。

1
2
3
4
5
6
2017-07-30 * "Coinbase" "BTC-> USD"
Assets:Crypto:Coinbase:Wallet -0.02000000 BTC {} @ 4500.00 USD
Expenses:Crypto:Commissions +3.00 USD
Income:Crypto:PnL -30.00 USD
Assets:Crypto:Coinbase:Wallet +87.00 USD

虽然人们对虚拟货币的货币属性仍有争议,但是对于比特币的转帐行为,交易费用是采用比特币结算的。这就给传统记帐手段带来了问题。对于 Beancount 来说,也比较 tricky,我也是找到这个讨论帖才找到如下这种记录方式。

1
2
3
4
5
2017-08-01 * "Bittrex" "Coinbase -> Bittrex"
Assets:Crypto:Coinbase:Wallet -0.01000000 BTC {}
Assets:Crypto:Bittrex:Wallet +0.00990000 BTC @ BTC
Expenses:Crypto:Commissions +0.00010000 BTC @ USD

上手

  • 先下载一个模板:https://github.com/mckelvin/beancount-boilerplate-cn/
  • 打开account.beancount,修改其中的帐号。帐号支持嵌套,加一个冒号就是子级。模板中还设计了多币种,我已经全部简化了。
    • 帐号名称不能用中文
    • 首字母必须大写
  • 初始化帐号,打开init.beancount,修改账户的初始余额。
  • 打开货币文件 commodity.beancount,删除不需要的基金和股票。
  • 打开价格文件 prices.beancount,删除不需要的价格,可以先手动更新,之后使用自动更新。
  • 可以使用balance命令来保证账户截止某一时间的金额,切忌时间要写+1天。

BQL收集

1
2
3
4
5
6
SELECT 
account, sum(cost(position)) as total, month
WHERE
account ~ "Expenses:*" and year = YEAR(today()) and month = MONTH(today())
GROUP BY month, account
ORDER BY total, account DESC

小结

  • 基金与其他投资标的:长期持有的话固定周期更新prices即可,如果需要每天的资产变动可以使用脚本每日更新。
  • 小额高频的变动,如手机余额、公交卡余额等可以计入消费。
  • 之后支付尽量使用同一平台,方便后期导出账单。
  • 原来经常不拿小票,自从开始复式记账之后就必须要拿小票了,不然都记不清自己买了什么,具体花了多少钱。
  • 虽然配置有些繁琐,学习概念也需要时间,但是如果你有和我一样的苦恼,我想这可能是唯一的选择。现在配置大致完成之后使用起来也很舒服,也不用不停的掏出手机记账了,晚上统一记录一下就好。
  • 后面会研究一下自动更新股票基金价格还有自动化导入,可能会再写一篇。
  • 如果有什么需要的可以留言反馈,大家共同进步。
作者

liukun

发布于

2021-06-10

更新于

2021-06-11

许可协议