Wealth Freedom OS

计算口径说明书

每一个财务数字是怎么算出来的,以及它不包含什么。

口径版本:3.0.0

这是一份正式的 Calculation Specification。它的作用是:同一个概念在整个产品里只有一个定义。

每一条口径都对应 @wealth-os/finance-core 里的一个导出函数,函数有独立的单元测试锁定行为。页面、计算器和将来的情景引擎都调用同一个实现,不许各自实现一套。公式含义变化时,版本号必须递增,并且已经保存的情景结果会据此被标记为需要重算。

怎么读这一页

每一节的结构是:公式 → 对应的函数 → 它排除了什么 → 容易搞错的地方。「排除了什么」往往比公式本身更重要:财务计算出错很少是因为算错了乘法,而是因为把不该算进去的东西算了进去。

10.1 净资产与流动净资产

Net Worth = Total Assets − Total Liabilities

对应 netWorth(snapshot)。它同时返回:

  • byLiquidity:资产按 cash / liquid / semi-liquid / illiquid 四档分组;
  • restricted:有使用限制或已指定用途的资产,连同原因;
  • staleValuations:估值日期早于快照日期的资产。

房产、未上市股权、养老金都算在净资产里,但它们的流动性与使用限制必须单独显示。房产和未上市股权的估值日期往往很旧,界面有义务把这个日期摊开。

Liquid Net Worth 是另一个数字,不是净资产的近似值。对应 liquidNetWorth(snapshot, options):

  • 分子:没有使用限制、没有指定用途的现金与流动资产。semi-liquid 默认不计入(它有价差、锁定期和交易周期),可以通过 includeSemiLiquid 打开;
  • 分母:horizonMonths(默认 12 个月)内需要偿付的负债。循环信贷与欠税按全额计入——「只还最低额就安全」不成立;其余按最低还款在这段时间里的累计额计入,上限是本金。

容易搞错

把流动净资产当成净资产的一个比例去估。一个人 80% 的资产是自住房时,净资产和流动净资产之间差的不是一个系数,而是「能不能应对下个月的意外」这件事本身。

10.2 可分配现金流

Free Cash Flow = 税后现金收入 − 生活支出 − 合同债务支付 − 其他强制现金流出

对应 monthlyCashFlow(snapshot)。所有频率先折成月额再相加,one-off 不构成周期现金流(按 0 处理,需要作为事件单独建模)。

税前收入必须写明税率才能折成税后现金:afterTaxMonthly 对没写 taxRate 的税前收入直接抛错,而不是默认当成税后。这是故意的——「大概是税后」会让后面所有数字都偏。

重复计算的陷阱

这里的「合同债务支付」是现金流出的全额,含本金和利息。其中的本金部分同时减少负债,所以它在净资产变化分析里还会出现一次。同一笔钱不能既算作现金流出的损失,又算作财富积累的来源——所以它在储蓄率里要单独列(见下一节)。

10.3 储蓄率

默认口径:

Savings Rate = 储蓄与投资的净增加额 ÷ 税后收入

对应 savingsRate(input)。它返回三个数:

  • savingsRate:默认口径;
  • expandedSavingsRate:(净增加额 + 本金偿还)÷ 税后收入;
  • principalContribution:本金偿还单独贡献的百分点。

界面必须把两个口径分开显示。税后收入为零或负数时函数抛错,因为这时候储蓄率没有意义——该用 Free Cash Flow 和 Runway 描述处境。

10.4 Runway

Runway = 可动用的安全资金 ÷ 月必要现金流出

对应 runway(snapshot)。

分子由 isSafetyAsset 判定,排除四类:

  1. 已经指定用于近期大额支出的钱(committedTo);
  2. 有使用限制的资产(restriction,如锁定期、质押、共同持有);
  3. 退休账户(即使里面是现金);
  4. 流动性不是 cash 或 liquid 的资产。

分母是 必要支出 + 最低债务支付 + 其他强制现金流出,不含可选支出。

必要流出为 0 时函数返回 null,而不是 Infinity——「无限个月」不是一个可以显示给人看的结论。

被排除的资产连同原因一起返回。这是 MVP 验收标准里的硬要求:已锁定、不可动用的资金不能直接加入安全储备,而且界面要能解释为什么。

算一算:收入明天中断,你能撑几个月口径 3.0.0
Runway
6.1 个月
可动用的安全资金 ÷ 月必要现金流出
计入的安全资金
90,000 元
共 2 项
月必要现金流出
14,700 元
必要支出 + 最低债务支付
月可自由支配现金
13,300 元
税后收入 − 生活支出 − 债务支付 − 其他强制流出
6 个月的应急金目标
88,200 元
距目标的缺口
已达标

没有计入安全资金的部分,以及原因

  • 养老金账户— 退休账户,不能及时无成本取用
  • 攒给首付的定存— 已指定用于明年的购房首付

把滑块里的钱从「活期」挪到「养老金账户」,总资产一分没少,Runway 会直接掉下来。这就是「有钱」和「现在能动用」的区别。

调用的口径: runway、emergencyFundGap、monthlyCashFlow

本次计算的假设:

  • 所有金额为人民币,不涉及汇率换算。
  • 必要支出保持不变——真实的收入中断往往同时抬高必要支出(医疗、搬迁),这个计算器不含这一层。
  • 安全资金不计利息,也不假设任何投资回报。
  • 分母是「必要支出 + 最低债务支付」,不含可选支出。
  • 养老金账户、有使用限制或已指定用途的钱不计入分子,即使它是现金。
  • Runway 只用到最低还款额,所以信用卡余额在这里按「月最低还款 × 12」凑了一个数,它不影响这一屏的结果。

这是教育性计算,不是投资建议,也不是对未来的预测。它只回答「在上面这些假设下,数字会是多少」。

应急金目标对应 emergencyFundGap(snapshot, targetMonths):目标 = 月必要流出 × 目标月数,缺口为负说明已达标。

目标月数没有标准答案。六个月是一个被重复太多次的数字,它取决于你的收入稳定性、行业重新就业的周期、家庭有几个人依赖这份收入、有没有可以兜底的社会支持。

10.5 收入集中度

Income Dependency = 最大的经济相关收入来源 ÷ 总收入

对应 incomeDependency(snapshot)。

关键在「经济相关」:同一雇主发出的工资和奖金共用一个 dependencyGroup,所以它们合成一组,不算两个独立来源。同一个大客户的多个项目也是一组。

这一条口径的存在是因为「我有三条收入」这句话经常是假的——三条都来自同一个行业、同一个平台或同一个客户时,它们会一起消失。

10.6 所有权收入比例

Ownership Income Ratio = 自己拥有的资产或企业产生的净收入 ÷ 总净收入

对应 ownershipIncomeRatio(snapshot)。

它只认已实现的现金收入。账面估值增长和潜在未来收入不进这个比值,它们在资产页单独看。

容易搞错

把未实现的资本增值当成日常可支配收入。账面涨了 30 万,和每个月多出 2500 元可以花的钱,是两件完全不同的事。分红也不是凭空增加的财富——它会相应降低资产价值,还要考虑税务影响。

10.7 Freedom Coverage

这里有两个覆盖率,不能相加,也不能互相替代。对应 freedomCoverage(snapshot, assumptions)。

Current Cash-flow Coverage

符合条件的非劳动净现金流 ÷ 必要生活支出。对应 currentCashFlowCoverage。

分子只认已经在到账的:租金、利息、分红、版税、养老金、企业分配,以及任何标记为由自己拥有的资产产生的收入。

Modeled FI Coverage

在明确假设与期限下估算的可持续资本支持额 ÷ 必要生活支出。对应 modeledFiCoverage。

默认假设:提款率 4%、期限 30 年、计入退休账户、不计入自住房权益、通胀 2%。

默认排除三类资产,每一条都会带原因返回:

  • 自住房权益——住在里面的房子不产生生活现金流;
  • 未上市权益与私募股权——估值与流动性都不确定;
  • 按假设排除的退休账户(可以打开)。

负债要从可支持资本里扣掉,但由已排除资产担保的负债要跟着一起排除,否则等于把房子剔掉又让房贷扣两遍。

为什么必须分开

一个人的 Modeled FI Coverage 是 1.2,Current Cash-flow Coverage 是 0.05。这意味着:在一组假设下资本够用,但现在每个月的生活费几乎全靠工作。把两者混为一谈,就会在收入中断时发现「够用」的那笔钱根本取不出来。所以 freedomCoverage 还会一起返回流动净资产。

10.8 FI Number

FI Number = 年支出 ÷ 假设提款率

对应 fiNumber(annualSpending, withdrawalRate) 与 fiNumberTable(annualSpending, rates)。

算一算:同一笔年支出,四个提款率假设口径 3.0.0
假设提款率对应资产规模相当于多少年的支出
3.0%4,800,000 元33.3 年
3.5%4,114,286 元28.6 年
4.0%3,600,000 元25.0 年
5.0%2,880,000 元20.0 年

3% 和 5% 之间差着近一倍的资产规模。所以「财富自由需要多少钱」这个问题,在没写明提款率、期限和支出口径之前是没法回答的。

调用的口径: fiNumber、fiNumberTable

本次计算的假设:

  • 年支出 = 月支出 × 12,按今天的购买力计,不含未来的通胀。
  • 提款率是一个假设,不是任何市场的安全收益率,也不是退休保证。
  • 不含税务、退休期限、资产结构、市场序列风险、养老金与其他收入。

这是教育性计算,不是投资建议,也不是对未来的预测。它只回答「在上面这些假设下,数字会是多少」。

这只是一道除法的敏感性示例。它不是任何市场的安全收益率,不是适合所有人的提款率,也不是退休保证。

实际建模还需要考虑:税务、通胀、退休期限、资产结构、市场序列风险、养老金和其他收入。其中序列风险尤其重要——同样的平均收益率,回报出现的顺序不同,结果可以差出一个量级。退休压力测试 讲的就是这件事。

债务计算

PRD 第 10 节没有单列债务口径,但验收标准要求「给定固定利率与付款计划时,计算结果可通过独立测试验证」。实现在 debt.ts:

  • 月利率 = 名义年利率 ÷ 12,按月计息,期初余额计息;
  • 月供先付利息,余下的冲本金;
  • 月供不足以覆盖当月利息时,不返回一个假的期数,而是返回 feasible: false 并给出 minimumViablePayment。这种情况下本金不会下降,计划本身不成立;
  • payoffPlan:每月先付所有最低还款,剩下的预算全部投向当前目标,一笔结清后它的最低还款并入预算;
  • 逾期的债务永远排在最前,无论用哪种策略。它的代价不是多付利息,而是违约后果。
算一算:同样的预算,先还哪一笔口径 3.0.0

这三笔债的最低还款合计 4,440 元。预算低于它,就不是「选哪种策略」的问题了。

顺序还清需要利息总额第一笔结清
雪球法(先还余额最小的)小额网贷 → 信用卡 → 消费分期20 个月11,863 元第 4 个月:小额网贷
雪崩法(先还利率最高的)信用卡 → 小额网贷 → 消费分期20 个月11,699 元第 13 个月:信用卡
雪崩法少付的利息
165 元
雪崩法少用的时间
一样

同一预算下,雪崩法少付约 164.52 的利息;雪球法先结清的笔数更多。哪一种更合适取决于你能否坚持。

调用的口径: compareStrategies、payoffPlan

本次计算的假设:

  • 固定利率,按月计息,期初余额计息;月供先付利息,余下的冲本金。
  • 最低还款按余额的固定比例估算(信用卡 5%、分期 3%、网贷 8%),真实合同可能不同。
  • 每月先付清所有最低还款,剩下的预算全部投向当前目标;一笔结清后它的最低还款并入预算。
  • 不含手续费、违约金、提前还款违约条款与协商减免。
  • 假设三笔债务都没有逾期。有逾期时任何策略都要先处理它,因为代价不是利息而是违约后果。

这是教育性计算,不是投资建议,也不是对未来的预测。它只回答「在上面这些假设下,数字会是多少」。

复利

对应 project(input)(compounding.ts):

  • 回报按年给出、按月折算:monthlyReturn = (1 + annual) ^ (1/12) − 1;
  • 费用按年从资产里扣,同样折成月。费用一直在反方向复利;
  • 允许负回报,曲线不保证向上;
  • 同时给名义值与扣除通胀后的实际值,两者不能混用。

ruleOf72 只用于教学中的量级直觉,不作为规划依据。

算一算:早期的钱是你投的,还是涨出来的口径 3.0.0 · 模型 0.1.0
期末余额(名义)
2,772,136 元
其中本金贡献
1,805,689 元
你自己投进去的钱
其中回报贡献
966,447 元
由回报假设产生的部分
累计费用
110,600 元
费用一直在反方向复利
第几年余额(名义)本金贡献回报贡献回报占余额
168,818 元67,200 元1,618 元2.4%
3222,183 元207,708 元14,474 元6.5%
5398,540 元356,774 元41,766 元10.5%
10958,105 元770,373 元187,733 元19.6%
151,728,219 元1,249,847 元478,372 元27.7%
202,772,136 元1,805,689 元966,447 元34.9%
回报累计超过投入的那一年
在 20 年里没有发生
在这一年之前,你的余额主要来自自己的收入
期末实际购买力
1,865,568 元
按 2% 通胀折回今天的钱,不要和名义值混用

储蓄率敏感性

  • 储蓄率 15.0% → 期末 2,079,102 元
  • 储蓄率 20.0% → 期末 2,772,136 元
  • 储蓄率 25.0% → 期末 3,465,171 元

前几年余额几乎等于你投进去的钱。能更快改变结果的是收入与储蓄率,不是再调高回报假设。

调用的口径: simulateFirstCapital、project

本次计算的假设:

  • 回报按年给出、按月折算;费用按年从资产里扣,同样折成月。
  • 每月投入 = 当年税后月收入 × 储蓄率;投入额按收入增长率逐年提高。
  • 通胀按 2% 折算实际购买力,名义值与实际值分开显示,不能混用。
  • 回报率是一个固定年率,不含真实市场的波动与顺序;允许为负。
  • 不含税务、交易成本与任何具体产品。

这是教育性计算,不是投资建议,也不是对未来的预测。它只回答「在上面这些假设下,数字会是多少」。

货币换算

对应 money.ts。这里没有「静默换算」的函数:convert 的返回值一定带着汇率、换算方法、汇率时间与来源,界面必须显示它们。缺汇率时抛 MissingRateError,而不是当成 1:1。

sumIn 把一组金额换算到同一币种再相加;任何一笔缺汇率都会抛错,不做部分求和——一个少算了几项的总额比报错更危险。

展示用的四舍五入在 round / roundMoney 里,计算过程中不调用它们:口径里没有中间取整。

这份口径不包含什么

  • 税务申报与具体税率计算;
  • 社保、公积金、医保的地区规则;
  • 任何具体金融产品的费用、申购赎回规则与准入条件;
  • 实时市场数据与估值;
  • 跨境税务居民身份的判定。

这些要么属于 Content Pack(地区相关、会过期、必须有核对日期和官方来源),要么必须由当地专业人士核实。

On this page