refactor: extract_fund_product.py 迁移至 beancount-importer-rust
Beancount 预算工具。独立的预算分析工具,输入账本与预算配置后自动生成预算统计与报告。
2026-06 绩效
--expand
--month
--from
--to
--year
budget: "数码, 爱好"
,
额外储蓄
投资.额外储蓄
--compare 2025-12
--sort-by
bucket_types
asset_bucket_accounts
budget:
Expenses:*
cargo build --release # 二进制在 target/release/beancount-budget-tool
假设你的账本长这样(my_ledger.bean):
my_ledger.bean
2026-06-16 * "工商银行" "地铁通勤" Expenses:Consume:交通 6 CNY Assets:Bank:工行 -6 CNY 2026-06-17 * "京东" "买耳机" budget: "数码" Expenses:Consume:电子 2000 CNY Assets:Bank:工行 -2000 CNY 2026-06-18 * "工商银行" "储蓄转入" budget: "储蓄" Assets:Bank:建设银行 5000 CNY Assets:Bank:工行 -5000 CNY
Step 1 — 写预算(my_budgets.yaml):
my_budgets.yaml
"2026-06": 生活费: 交通: 1500 饮食: 2500 数码: 3000 储蓄: 10000
Step 2 — 写映射(my_mappings.yaml):
my_mappings.yaml
default_expense_bucket: 生活费 defaults: "Expenses:Consume:交通": 生活费.交通 "Expenses:Consume:电子": 数码 asset_bucket_accounts: 储蓄: - "Assets:Bank:建设银行"
bucket_types 可以省略——asset_bucket_accounts 中出现的桶自动识别为 asset,其余默认 expense。
Step 3 — 运行:
beancount-budget-tool -l my_ledger.bean -m 2026-06 \ --budgets my_budgets.yaml --mappings my_mappings.yaml --scope cumulative
输出:
预算报告 (2026-06 (cumulative)) [CNY] 预算桶 月预算 已支出 使用率 结余 状态 -------------------------------------------------------------- 储蓄 10000.00 5000.00 50.0% 5000.00 正常 数码 3000.00 2000.00 66.7% 1000.00 正常 生活费 4000.00 6.00 0.2% 3994.00 正常 -------------------------------------------------------------- 合计 17000.00 7006.00 41.2% 9994.00 正常
四种 key 格式:
# 1. 月度(YYYY-MM) "2026-06": 数码: 3000 旅行: 2000 # 2. 具体日期(YYYY-MM-DD) "2000-08-20 对方还款": 生活费: 500 # 3. 月度 + 标签(绩效、年终奖等,与基础月预算叠加) "2026-06 绩效": 旅行: 2000 # 4. 嵌套层级 → 自动展平为 生活费.交通、生活费.饮食 "2026-06": 生活费: 交通: 1500 饮食: 2500
生活费
生活费.交通
--bucket 生活费
--bucket 生活费.交通
YYYY-MM-DD
default_expense_bucket: 生活费 # 无匹配时的兜底桶 # bucket_types 是可选的:asset_bucket_accounts 中出现的桶自动推断为 asset # 只有需要显式声明时才写 bucket_types: 储蓄: asset defaults: # 账户前缀 → 桶名(最长前缀优先) "Expenses:Consume:交通": 生活费.交通 "Expenses:Consume:电子": 数码 asset_bucket_accounts: # 可选:资产桶的账户前缀 储蓄: - "Assets:Bank:建设银行" - "Assets:Invest:货币基金"
defaults
2026-06-17 * "京东" "买耳机" budget: "数码" Expenses:Consume:电子 2000 CNY Assets:Bank:工行 -2000 CNY
程序兼容 Tab 缩进和单空格分隔,但建议用 Beancount 标准格式(至少两个空格分隔账户与金额)。
2026-06-20 * "京东" "买耳机和游戏" budget: "数码, 爱好" Expenses:Consume:电子 2000 CNY Assets:Bank:工行 -2000 CNY
数码和爱好各计支出 2000。
三种写法等价,支持中文逗号 , 混用:
; 半角冒号 + 英文逗号 budget: "电子产品:900, 旅游:900, 保险:200" ; 全角冒号(不用切输入法)+ 中文逗号 budget: "电子产品:900,旅游900,保险200" ; 无分隔符(尾部数字自动识别) budget: "电子产品900, 旅游900, 保险200"
配合 asset_bucket_accounts 可独立追踪各桶的资金位置及后续消费扣减。
写 额外储蓄 会自动查找 *.额外储蓄 的完整桶名,所以:
*.额外储蓄
budget: "额外储蓄13847" # → 自动匹配到 投资.额外储蓄 budget: "待投资金2000" # → 自动匹配到 投资.待投资金
--bucket 额外储蓄 同样自动补全。
--bucket 额外储蓄
工资分桶在 budgets.yml 里做,不写标签。零星收入写 budget: "生活费" 即可入账抵消支出:
budgets.yml
budget: "生活费"
2026-04-03 * "广告" "广告费" budget: "生活费" Income:Misc:广告 -50 CNY Assets:Bank:工行 50 CNY
Income 只有显式写 budget: 标签的才入桶,不写标签的收入(工资、退款等)不影响预算。
budgets.yml 里写 planned: 0,只看不设预算:
planned: 0
"2026-06": 大额支出: 0 # 仅跟踪,不计入预算总额
budget: "数码, 大额支出" # 花费同时计入数码预算和大额支出跟踪
汇总表中跟踪桶排在底部,合计不纳入其 actual。
纯资产转移(只有 Assets↔Assets)不会凭空生成支出,而是自动记录位置变动。超支时「持仓/已分配」段隐藏,仅显示「超支/出金来源」。
链路中每段都可写 budget:,不重复算支出:
# 只有最后一段(有 Expenses: 行)才算支出 2026-04-02 * "京东" "买MacBook" budget: "数码" Expenses:Consume:电子 12000 CNY Assets:Invest:货币基金 -5000 CNY Assets:Bank:工行 -7000 CNY → 支出 12000,位置扣减 Fund+Bank
2026-05-16 * "工行" "机票" #东京 #家族旅行 ^trip-2026 budget: "旅行" Expenses:Travel 5000 CNY
标签被提取为 metadata,配合 --filter 搜索。
--filter
2026-06-16 * "工行" "地铁" ; 没写 budget Expenses:Consume:交通 6 CNY ; → 前缀匹配到 生活费.交通 2026-06-19 * "淘宝" "杂货" ; 没写 budget Expenses:Consume:杂货 50 CNY ; → 无匹配,回退到 生活费
-l, --ledger <FILE>
--ledger-dir <DIR>
.bean
.beancount
-m, --month <YYYY-MM>
--from/--to/--year
--from <YYYY-MM>
--to <YYYY-MM>
--year <YYYY>
--from YYYY-01 --to YYYY-12
--budgets <FILE>
--mappings <FILE>
--scope <month|cumulative>
month
--bucket <NAME>
--bucket-view <summary|monthly|detail>
summary
--filter <KEYWORD>
--sort-by <name|planned|actual|remain>
name
--compare <YYYY-MM>
--show-locations
--hide-asset-flows
--out-dir <DIR>
--csv-pivot
--out-json
--currency <CODE>
CNY
--strict
--month 2026-06 --scope month # 仅 6 月 --month 2026-06 --scope cumulative # 最早 ~ 6 月 --from 2026-03 --to 2026-06 # 3 ~ 6 月 --year 2026 # 2026 全年
# 今年的整体预算执行情况 --year 2026 # 展开子桶看明细 --year 2026 --expand # 今年 vs 去年对比 --year 2026 --compare 2025-12 # 按超支程度排 --year 2026 --sort-by remain # 搜旅行桶里"东京"相关的消费 --bucket 旅行 --bucket-view detail --filter "东京" # 导出全年报告 + 横向月度 CSV --year 2026 --out-dir ./reports --csv-pivot
summary-{range}.md
.txt
buckets-{range}.csv
bucket-{桶名}-{range}.md
asset-locations-{桶名}-{range}.md
pivot-{range}.csv
summary-{range}.json
--scope month
--scope cumulative
> tmp.txt
examples/ 目录下:
examples/
budgets.yaml
mappings.yaml
demo.bean
版权所有:中国计算机学会技术支持:开源发展技术委员会 京ICP备13000930号-9 京公网安备 11010802047560号
beancount-budget-tool
Beancount 预算工具。独立的预算分析工具,输入账本与预算配置后自动生成预算统计与报告。
功能
2026-06 绩效)--expand展开子桶)--month/--from/--to/--year)budget: "数码, 爱好"逗号分隔,各计全额;支持中文逗号,)额外储蓄→投资.额外储蓄)--compare 2025-12并排展示两期数据)--sort-by)bucket_types可选:asset_bucket_accounts中的桶自动推断为 assetbudget:的Expenses:*自动归入默认生活费桶构建
5 分钟上手
假设你的账本长这样(
my_ledger.bean):Step 1 — 写预算(
my_budgets.yaml):Step 2 — 写映射(
my_mappings.yaml):Step 3 — 运行:
输出:
配置说明
budgets.yaml
四种 key 格式:
生活费是父桶,生活费.交通是子桶。父桶统计自动由子桶之和得出。--bucket 生活费汇总全子桶,--bucket 生活费.交通只看交通。YYYY-MM-DD)的月份部分用于范围过滤,日期信息保留在标签中展示。mappings.yaml
defaults行,只有显式写budget:才入桶。bucket_types**:asset_bucket_accounts中的桶自动识别为 asset。Beancount 交易标注
基本用法
多桶归属
数码和爱好各计支出 2000。
桶名:金额 / 桶名900(基金拆分)
三种写法等价,支持中文逗号
,混用:配合
asset_bucket_accounts可独立追踪各桶的资金位置及后续消费扣减。简写桶名自动补全
写
额外储蓄会自动查找*.额外储蓄的完整桶名,所以:--bucket 额外储蓄同样自动补全。Income 标签通道
工资分桶在
budgets.yml里做,不写标签。零星收入写budget: "生活费"即可入账抵消支出:Income 只有显式写
budget:标签的才入桶,不写标签的收入(工资、退款等)不影响预算。跟踪桶(纯统计不预算)
budgets.yml里写planned: 0,只看不设预算:汇总表中跟踪桶排在底部,合计不纳入其 actual。
Expense 桶自动退化
纯资产转移(只有 Assets↔Assets)不会凭空生成支出,而是自动记录位置变动。超支时「持仓/已分配」段隐藏,仅显示「超支/出金来源」。
支付链路标注
链路中每段都可写
budget:,不重复算支出:#tag / ^link(Beancount 原生标签)
标签被提取为 metadata,配合
--filter搜索。不写 budget(自动归类)
CLI 参数
-l, --ledger <FILE>--ledger-dir <DIR>.bean/.beancount-m, --month <YYYY-MM>--from/--to/--year互斥--from <YYYY-MM>--to)--to <YYYY-MM>--from)--year <YYYY>--from YYYY-01 --to YYYY-12)--budgets <FILE>--mappings <FILE>--scope <month|cumulative>month--bucket <NAME>--bucket-view <summary|monthly|detail>summary--filter <KEYWORD>--sort-by <name|planned|actual|remain>name--expand--compare <YYYY-MM>--show-locations--hide-asset-flows--out-dir <DIR>--csv-pivot--out-json--currency <CODE>CNY--strict时间范围示例
常用组合
输出文件
summary-{range}.md/.txtbuckets-{range}.csvbucket-{桶名}-{range}.mdasset-locations-{桶名}-{range}.mdpivot-{range}.csv(需--csv-pivot)summary-{range}.json(需--out-json)注意事项
--scope month只看当月位置,--scope cumulative看全部历史。budget:的 Income 入桶,不写标签的(工资、退款等)完全忽略。> tmp.txt正常显示。完整示例
examples/目录下:budgets.yamlmappings.yamldemo.bean