Beancount

使用 chatGPT 编写自动添加 beancount balance 断言语句

我使用 beancount 记账流程中的有一步是这样的,将每张信用卡的账单日添加到滴答清单中,每月重复。 每当到达账单日时,提醒我在 beancount 文件中添加一条对应帐目的 balance 断言语句,由于大部分信用卡 的出账是有滞后的,所以该balance断言通常需要同时加上!标记,便于后续账单出来后修改。

这个过程是比较机械的,所以我想到了使用 chatGPT 来自动化这个过程,这样我只需要在出账后手动更新自动添加 的断言语句,将金额修改为正确的还款金额,同时去除!标记。最终的脚本如下。

import datetime

def add_balance_statement(ledger_path, account, date, balance, currency):
    with open(ledger_path, 'a') as file:
        file.write(f"{date} balance {account} {balance} {currency}\n")

def auto_add_balance_statements(ledger_path, credit_cards):
    today = datetime.date.today()
    for card in credit_cards:
        bill_date = card['bill_date']
        accounts = card['accounts']
        balance = card['balance']
        currency = card['currency']
        if today.day == bill_date:
            for account in accounts:
                add_balance_statement(ledger_path, account, today, balance, currency)
                print(f"Balance statement added for {account} on {today}.")

# Specify the path to your Beancount ledger file
ledger_file_path = "<ledger_path>"

# Specify your credit card details (bill date, accounts, balance, and currency)
credit_cards = [
    {
        'bill_date': 1,  # Example: 1st of the month
        'accounts': [
            {'account': 'Assets:CreditCards:Card1:Account1', 'currency': 'USD'},  # Example: Account1 for Card1 with USD currency
            {'account': 'Assets:CreditCards:Card1:Account2', 'currency': 'EUR'},  # Example: Account2 for Card1 with EUR currency
        ],
        'balance': 1000.00,  # Example: Current balance for Card1
        'currency': 'USD'  # Example: Currency for Card1
    },
    {
        'bill_date': 15,  # Example: 15th of the month
        'accounts': [
            {'account': 'Assets:CreditCards:Card2:Account1', 'currency': 'USD'},  # Example: Account1 for Card2 with USD currency
            {'account': 'Assets:CreditCards:Card2:Account2', 'currency': 'GBP'},  # Example: Account2 for Card2 with GBP currency
        ],
        'balance': 2000.00,  # Example: Current balance for Card2
        'currency': 'USD'  # Example: Currency for Card2
    },
    # Add more credit card details as needed
]

# Call the function to automatically add balance statements
auto_add_balance_statements(ledger_file_path, credit_cards)

对于有兴趣的读者,可以看我和 chatgpt 的几轮对话。

...

用于 beancount 快速记账的 Telegram Bot

当年从随手记迁移到桌面记账方式(Excel/GnuCash/Beancount)后,确实有一段时间的不适应。 后来实在没有找到好用的移动端记账 APP,同时也适应了桌面记账,遂被驯化认为不需要在移动场景 记账。Costflow 出来之后没有第一时间尝试的原因也在于此,使用一段时间基于 costflow 语法 的 Telegram 机器人之后,发现经常是想要的账户没有配置,导致使用频率并不高。

前段时间的某一天突然意识到,为什么要提前配置账户信息呢?账户信息全部都在账本文件中,直接 查询账本文件不就可以避免冷启动的问题么。遂自己开坑写了一个新的记账机器人 beancount-bot

使用一月有余,今天完善了一下相关功能,更新了文档和使用例子。下面是几点简要说明:

  1. 适合手动记账党 :D
  2. 适合有自己服务器的人(境内服务器需要配置代理),部署在本地 NAS 上也是可行的
  3. 不兼容 costflow 语法,不需要账户信息的配置,账户的匹配是读取账本文件,类似编辑器的账户补全

在这里分享给大家,希望可以节省一点记账/对账的时间,有兴趣的欢迎尝试。

Beancount 账户命名

命名是计算科学中最难的两件事,Beancount 的账户的命名尤其困难。对于从其他记账工具迁移过来的用户,直接将原先的账户结构迁移过来当然是可以的。但是 Beancount 这种文本记账工具,对于账户的处理几乎没有成本,可以任性地添加更多的账户。直接复制原来工具的账户结构可能无法完全发挥 Beancount 的能力。

我个人为 Beancount 的账户命名有提供以下几点指导:

  1. 账户命名在可接受的范围内尽量详细,有账户补全这样的功能在,多级账户名锁造成的额外负担是很小的。带来的好处是显而易见的,最终形成的报表详尽而清晰。此外,在后期使用正则替换合并账户是很容易的,但是拆分账户只能对每一条记录进行检查。
  2. 多使用多级账户,在 fava 中折叠次级账户后,可以清晰地看到上一级账户的总额。
  3. 尽量遵从你的直觉,想象你在以后遇到一笔账户,直觉告诉你应该放到哪个账户。这样可以最大地降低记账的认知负担。当然,这一点可以随着使用慢慢优化自己的账户命名,毕竟文本账本的一大优点就是可以方便地进行正则替换。

最后附上一些其他记账工具默认的账户命名,可供参考。

  • MoneyWiz 默认账户名

      Automobile
          Accessories
          Car Insurance
          Gas/Fuel
          Lease
          Maintenance
          Other
          Parking
      Bills
          Cable
          Electricity
          Gas
          Internet/Broadband
          Mobile Phone
          Other
          Phone
          Water
      Clothing
          Accessories
          Clothes
          Jewelry
          Other
          Shoes
      Digital
          Apps
          Books
          Movies
          Music
          Other
          Podcasts
          TV Shows
      Food & Dining
          Dining/Eating Out
          Groceries
          Other
      Health Care
          Dental
          Eye Care
          Health Insurance
          Medical
          Other
          Pharmacy
      Housing
          Furniture/Accessories
          Home Insurance
          Maintenance
          Mortgage
          Other
          Rent
      Leisure
          Entertainment
          Fitness/Sport
          Other
          Personal Care
      Loans
          Other
          Taxes
          Transportation
          Travel
    
  • mint-categories https://www.mint.com/mint-categories

    ...

Beancount 投资回报计算与可视化

TL;DR 使用 fava-portfolio-returns1 ,可在 fava 中直观展示投资回报率详细数据,该插件的数据来源是 beangrow2

几种方案概述 #

fava-portfolio-returns + beangrow #

对于使用 Beancount 记录投资帐目的人来说,如何评估自己的投资回报一直是一个未解决的问题。前一段时间 Beancount 的开发者 Martin 写了一个计算回报率的小工具32,姑且可以算是 v3 版本功能的一个小前瞻,尝试使用之后,虽然目前还是比较粗糙的脚本,但是基本可以计算出来年化的投资回报率了。Beancount 用户 Redio 也写了详细的 Review4,可以作为第一个文档的补充,使用时参考。

2023-08-29 更新 近日在邮件列表看到了 fava-portfolio-returns1 项目,这是一个用于在 fava 中展示投资历史回报的插件,后端数据来自 beangrow,尝试了一下发现运行良好,当然运行良好的前提是解决一堆报错,这个插件对 beangrow 配置文件的错误容忍程度较低,遇到错误时可开启 debug 模式查看报错信息。这里放两张官方的截图,展示了该插件的功能。具体使用方法参见官方仓库 README。

![report_overview]({{ site.cdn_url }}/img/report_overview.png)

![report_vht]({{ site.cdn_url }}/img/report_vht.png)

fava_investor #

fava_investor 5 是另一个试图在 fava 中进行投资回报可视化的插件,目前处于开发中,由于我的投资帐目比较复杂,目前没有办法成功运行。对于简单的投资帐目(例如不包含数字货币),可以尝试使用。

beancount_portfolio_report #

另外还有一些比较小的工具,例如 beancount_portfolio_allocation6是一个根据当前市值计算持有资产比例的脚本,方便用来进行资产重新配置。我在此插件的基础上,进行了一些简单的修改,重新命名为 beancount_portfolio_report7,用于输出当前各类资产的市值、回报和总体回报率(非年化)。

beancount-boilerplate-cn #

beancount-boilerplate-cn 有部分净值计算的工具,但是同样不适合我这种比较复杂的投资记账。没有尝试。

beancount.io #

beancount.io 在网站上也提供了 Stock Analysis 工具,可惜没有看到开源,处于数据安全顾虑,目前没有体验。从 demo 来看完成度还是比较高的。侧重点在于比较不同风险资产的盈利情况。

...

关于记账工具

本文记录个人关于记账以及记账工具选择的一些想法和经验。

你需要记账吗? #

记账利弊皆有,因人而异。最重要一点,记账可以帮助你清晰量化地认识个人收支情况。我是一个喜欢量化存档生活的人,以前会备份各种聊天记录、短信、通话记录等信息,日常也有写日记的习惯,账本相当于另一个维度的日记。

记账让我对自己的生活有更强大的掌控感(也许是错觉)。据说记账有以下缺点,可能会让人变小气,太麻烦等,读者根据自己的实际情况考虑。记不记账纯属个人选择,若您有兴趣开始记账的习惯,希望本文可以提供一点参考。

记账基本原则 #

  1. 收付实现制与权责发生制 我采用收付实现制记账原则,与之对应的另一个词是权责发生制,举个简单的例子说明二者的含义。拿交房租来说,年初你交了未来半年的房租 12000 CNY,收付实现制会这么记账,年初支出 12000 CNY,只有这 1 笔。权责发生制会这么记,未来的 6 个月,每月支出 2000 CNY,共 6 笔。 个人采用的是前者,即收付实现制,主要优点是方便对账,毕竟银行的流水只有 1 笔 12000 CNY 的。他的缺点也很明显,会导致月度财务报表并不准确,不能清晰反应月度收支情况。所以采用收付实现制,在查看报表的时候,不应简单的去看数字的绝对值。

  2. 负支出 电商购物退款退货的场景很常见,月初买了一个东西,记了一笔支出,到货后发现不合适申请退货,中旬退款回到原支付渠道。我该怎么记这笔退款呢?省事的办法是把月初记的支出那笔删除,还有一个办法是退款导致时记一笔收入。但是聪明的你一定会发现这两种方法都不太理想,前者不能反应真实流水,后者会导致月度报表支出与收入都虚高。 比较合理的做法是退款时记录一笔负支出。当你意识到支出可以是负的时候,很多帐目记起来就简单多了。

记账工具 #

1.移动设备

主要是 Android 和 iOS 两个平台。主流的记账工具基本都是全平台的了。其中功能丰富占据大部分用户的记账应用有二:

  • 随手记,我使用随手记时在论坛提出的关于多币种的问题1
  • 挖财
  • MoneyWiz, iOS

对于入门者,推荐使用这二者之一开始。基本满足大部分功能需求。

对于不需要如此复杂功能,例如多账户的用户来说,也可以选择很多主打简洁的应用,例如 iOS 下的 Expense。由于我不是 Android 用户,所以此平台下的轻量级应用请自行寻找。

2.桌面

桌面的记账方法相对来说比较严肃,简单的可以采用 Excel 记账,复杂的可以采用专业的财务软件。总结来说:

  • MoneyWiz, macOS
  • Excel, 网上寻找他人分享的记账模板,略加修改便可以使用
  • Gnucash, 开源软件,多平台支持。复式记账,多币种记账。Windows 下的桌面客户端虽然丑陋但是可用,功能强大
  • Ledger, 简单的命令行记账工具,复式记账
  • Beancount, Python编写,命令行工具,多币种记账功能强大,复式记账。可以认为是 Ledger 的升级版。可以参考推特上的讨论2

以上软件按照新手友好程度排列。

...