Personal Finance Consolidator(个人资产收支多账本归一解析)
Overview
将零散的个人账单归一到单一 SQLite 账本:多账本(招行/支付宝/微信/现金…)、多币种自动换算基准币种、跨境收支打国家标签、固定资产直线法折旧、往来债权债务(应收/应付)跟踪、图片截图 OCR 识别,最后自动对账去重并生成资产快照。
何时使用
- 用户有多份账单文件(银行流水 CSV、支付宝/微信导出、信用卡 Excel、PDF 对账单、账单截图/照片)想合并统计
- 需要多币种收支归一(如 USD/EUR 消费按汇率折算 CNY)、跨境收支统计
- 需要登记固定资产并按月折旧计算净值
- 需要记录借出/借入(债权债务)并纳入净资产
- 需要月度收支、分类支出、资产快照报告(Markdown/HTML)
工作流
1. 初始化
cd ~/.workbuddy/skills/personal-finance-consolidator/scripts
export PF_DIR=~/finance # 数据目录(默认 ~/.finance,可用环境变量覆盖)
python3 pf.py init --base CNY # 基准币种,默认 CNY
python3 pf.py ledger --add 招行信用卡 --currency CNY
python3 pf.py account --add 招行储蓄 --ledger 个人 --type bank --opening 50000
python3 pf.py account --add 招行信用卡 --ledger 招行信用卡 --type credit
2. 导入账单(自动识别格式)
python3 pf.py import 账单.csv --ledger 个人 --account 招行储蓄
python3 pf.py import 对账单.xlsx --ledger 支付宝 --account 余额 --kind expense
python3 pf.py import 流水.pdf --ledger 信用卡
python3 pf.py import 截图.png --ledger 现金 --status pending --country US
- CSV/Excel 表头别名自动映射(日期/金额/摘要/类型/对方/分类/币种/国家 的中英文常见写法,见
pfcore/importers.py的 HEADER_MAP) - 图片/截图走 macOS Vision OCR(需
pip install ocrmac),启发式解析日期/金额/描述,建议--status pending人工复核后再确认 --kind income|expense可整文件强制收支方向(如全部是支出)--country US可整文件打跨境国家标签- 外币交易自动按当日汇率换算基准币种(
pf fx批量更新,离线自动兜底内置汇率)
3. 手动记账
python3 pf.py add --desc "工资" --amount 15000 --kind income --date 2026-08-01 --account 招行 --category 工资 --counterparty 公司
python3 pf.py add --asset "MacBook Pro" 2025-01-15 --amount 19999 --currency CNY --years 3 --category electronics
python3 pf.py add --debt receivable 张三 --amount 5000 --date 2026-06-01 --due 2026-12-31 --desc 借款
python3 pf.py add --debt payable 李四 --amount 300 --currency USD --date 2026-07-01 --desc 代付
4. 对账去重(跨账本自动对齐)
python3 pf.py align
对账分两类匹配(互斥,一笔交易只属于一类):
跨账户转账 (transfer) — 银行提现到微信、微信转支付宝、信用卡还款等
- 条件:跨账本 + 反向(一边 income 一边 expense)+ 日期 ≤3 天 + 金额相等/汇率换算后 ±1%
- 信号:任一方描述含转账关键词(转账/转入/提现/充值/还款入账/银行卡/信用卡还款…),或描述相似度 ≥0.6,或精确金额匹配且日期差 ≤1 天
- 借贷排除:描述含"借给/借款/借出/借入/欠"的交易属债权债务往来(如"借给朋友A" ↔ "朋友还款"),即使反向同额也不判转账,保持 confirmed 并登记债权台账
- 处理:组内全部标
transfer状态 → 收支统计排除(不重复计算收入/支出),但账户余额仍计入(钱确实流动了) - 支持转账链:银行→微信→支付宝,多笔自动归入同一组
跨账本重复 (duplicate) — 同一笔消费出现在信用卡账单 + 银行流水
- 条件:跨账本 + 同向(两边同为 income 或同为 expense)+ 日期 ≤3 天 + 金额 ±1% + 描述相似度 ≥0.6
- 处理:组内首条保留
confirmed,其余标duplicate(收支统计排除)
> ⚠️ 对账只跨账本:同一账本内不会重复记账,月度固定支出(工资/社保等)金额相同属正常,不会被误判。单账本数据(如单独一个经营账本)无需也不应跑 pf align,快照生成时内部会自动做跨账本对账,不会影响单账本数据。
5. 预算与提醒
# 设置预算(范围:overall 总 / category 分类 / account 账户 / ledger 账本)
python3 pf.py budget set --scope overall --amount 30000 --period monthly
python3 pf.py budget set --scope category --target 餐饮 --amount 2000 --period monthly
python3 pf.py budget set --scope account --target 招行储蓄卡 --amount 15000 --period monthly
python3 pf.py budget set --scope ledger --target 支付宝 --amount 5000 --period monthly
python3 pf.py budget set --scope overall --amount 300000 --period yearly --note 年度总预算
python3 pf.py budget list # 查看全部预算
python3 pf.py budget report --month 2026-08 # 预算执行报告(默认当月)
python3 pf.py budget update 1 --amount 50000 # 修改预算
python3 pf.py budget del 1 2 # 删除预算
python3 pf.py remind --due-in 7 # 提醒:预算超支/将超、债务逾期/临近到期、待复核
- 预算执行报告:实际支出(confirmed expense)/ 剩余 / 使用率 / 时间进度(当月已过天数比例),使用率 ≥80% 警告、≥100% 超支;期间未结束时对比时间进度给出「超前/偏慢/正常」节奏提示
- 分类预算
--target 未分类会匹配未打分类的支出(category 为空) - 提醒等级:🔴 超支/逾期 → 🟠 预警/临近到期 → 🔵 待办(pending/duplicate)
- 快照会自动附上「预算执行」与「提醒」两个区块,顶部显示待办提醒横幅
- 提醒项会附带「查看 X 条关联数据」折叠表格:预算提醒展开预算额度/已支出/使用率;债务提醒展开往来方/金额/到期日;待确认/疑似重复提醒展开具体交易(日期、账本、账户、描述、金额、状态),无需人工在别处查找
6. 资产快照
python3 pf.py snapshot --format both --out 快照 # 同时生成 快照.md + 快照.html
python3 pf.py snapshot --format html --out 快照.html
快照含:净资产、总资产/负债、账户余额、固定资产折旧净值、债权债务、月度收支、分类 TOP10、跨境收支、汇率、数据健康度。HTML 为自包含文件(内嵌 CSS/图表,无外部依赖),可直接分享。
6. 其他
python3 pf.py status # 账本/交易/资产概览
python3 pf.py export # 全部交易导出 CSV(UTF-8 BOM,Excel 直接打开)
python3 pf.py fx # 更新汇率(frankfurter.app,ECB 参考价,离线自动兜底)
7. 定时提醒(可选)
需要定期收到预算/债务提醒时,可让 AI 助手创建定时任务(如每天早晨跑 pf remind 并把结果发到对话)。数据目录通过 PF_DIR 环境变量指定。
依赖
标准库即可跑通 CSV/JSON/手动记账。可选:
python3 -m venv ~/.finance/venv
~/.finance/venv/bin/pip install -r scripts/requirements.txt
# openpyxl(Excel) pdfplumber(PDF) ocrmac(图片OCR, macOS Vision)
关键设计决策(勿随意改动,改前先读 references/schema.md)
- 基准币种:settings 表
base_currency(默认 CNY),所有外币交易存原币amount+ 归一值amount_base(带符号:收入正/支出负) - 汇率语义:
1 quote_currency = rate base_currency,优先当日历史缓存 → 实时抓取 → 内置默认兜底 - 对账规则:分两类——
- 跨账户转账:跨账本 + 反向(income↔expense) + 日期 ≤3 天 + 金额 ±1%,信号为转账关键词/描述相似/精确金额+日期差≤1天;描述含"借给/借款/借出/借入/欠"者排除(借贷往来非转账);组内全部标
transfer(收支统计排除,账户余额仍计入) - 跨账本重复:跨账本 + 同向 + 日期 ≤3 天 + 金额 ±1% + 描述相似度 ≥0.6(Jaccard+包含度取最大);组内首条 confirmed,其余 duplicate
- 同账本疑似重复:同账本同账户同日同额描述相似度≥0.9 → duplicate
- 折旧:直线法
月折旧 = (原值 - 原值×残值率) / (年限×12),双倍余额递减法备选;已处置资产按处置日截断 - 导入默认 confirmed;图片 OCR 结果建议
--status pending待人工复核(OCR 可能误识别) - 跨账户转账:
pf align自动识别银行→微信→支付宝等转账链,标transfer状态后收支统计自动排除(income_expense只计 confirmed),账户余额仍含 transfer(account_balances包含 confirmed/pending/transfer 三种状态)
常见问题
- 外币交易未匹配:对账要求币种一致或换算后 ±1%。若信用卡账单未导币种列,外币消费会因默认 CNY 而匹配失败——在导入文件补充币种列,或用
pf add手动补记。 - 汇率偏差:frankfurter 只覆盖 ECB 参考货币(约 30 种),UZS/IRR/PKR 等小众币种用内置默认汇率,可接受或手动校准。
- OCR 误识别:图片导入后先
pf status看 pending 数量,用pf export --status pending复核后再确认。