以下情境为教学假设,人物与数字不代表经核实的真实案例。
三个案例的估值锚看上去差距很大:LedgerLite 是 3.2× ARR,Tidecast 是 1.8× 收入,Nord Studio 是 4.5× SDE。3.2、1.8、4.5 这三个数字放在一起,很容易得出「Nord 最贵、Tidecast 最便宜」的结论。这个结论是错的,因为三个倍数的分母根本不是同一个东西。
这一节做三件事:先把三个锚换算成同一个分母,再在相同收入规模下比较经常性与一次性结构的估值区间,最后解释为什么 Nord 的 4.5× SDE 换算成收入只有约 1.0×。核心口径只有一句:倍数不能直接比较,先换分母,再谈价格。
先看三个锚的原始定义:
| 案例 | 披露锚 | 分母 | 分母金额 | 估值金额 |
|---|---|---|---|---|
| LedgerLite | 3.2× ARR | ARR | $240,240 | $768,768 |
| Tidecast | 1.8× 收入 | 净收入 | $138,171 | $248,708 |
| Nord Studio | 4.5× SDE | SDE | $34,320 | $154,440 |
| Nord Studio(折价) | 3.0× SDE | SDE | $34,320 | $102,960 |
这张表里已经藏了三个不可比因素。第一,LedgerLite 的分母是 ARR,Tidecast 是净收入,Nord 是 SDE;ARR 只含经常性收入,净收入已经扣了退款和平台分成,SDE 是毛利减运营费用。第二,三个分母的金额不同,直接比较倍数等于忽略了规模。第三,估值金额的口径也可能不同,有的是资产收购价,有的是股权价;本节只比较「估值金额 ÷ 分母」这一层,不展开交易结构。
三个锚,三个分母
LedgerLite 的 3.2× ARR 最接近「收入倍数」的直觉,因为 ARR 就是年度经常性收入:
ARR = MRR × 12 = 20,020 × 12 = $240,240
估值 = 3.2 × 240,240 = $768,768
Tidecast 的 1.8× 收入用的是净得,不是标价收入:
标价收入 = 19.99 × 9,600 = $191,904
净得 = 191,904 − 退款 7,676 − 平台分成 44,215 − 支付费 1,842
= $138,171
估值 = 1.8 × 138,171 = $248,708(1.8 × 138,171 = 248,707.8)
Nord Studio 的 4.5× SDE 用的既不是收入,也不是利润,而是 SDE:
SDE = 毛利 − 运营费用 = 130,320 − 96,000 = $34,320
估值 = 4.5 × 34,320 = $154,440
SDE 是「卖方自由现金流」的近似,已经把两人工资 $96,000 扣掉。它衡量的是「买方接手后,在支付管理人员工资之前能拿到的现金」。用 SDE 做分母,适合利润薄、老板薪酬影响大的小生意;用 ARR 做分母,适合经常性收入主导的订阅生意。两种分母服务两种买家,不能直接比。
把倍数换成同一把尺
要比较三个锚,最直接的办法是把它们都换算成「估值 ÷ 收入」:
| 案例 | 估值 | 收入口径 | 收入金额 | 换算后的收入倍数 |
|---|---|---|---|---|
| LedgerLite | $768,768 | ARR | $240,240 | 3.200× |
| Tidecast | $248,708 | 净收入 | $138,171 | 1.800× |
| Nord Studio | $154,440 | 收入 | $154,320 | 1.001× |
| Nord Studio(折价) | $102,960 | 收入 | $154,320 | 0.667× |
换算公式就是:
收入倍数 = 估值 ÷ 收入
LedgerLite 是 768,768 ÷ 240,240 = 3.2;Tidecast 是 248,708 ÷ 138,171 ≈ 1.8;Nord 是 154,440 ÷ 154,320 ≈ 1.001;折价后的 Nord 是 102,960 ÷ 154,320 ≈ 0.667。
换算之后,结论完全变了:Nord 的 4.5× SDE 听起来最高,换算成收入只有约 1.0×;Tidecast 的 1.8× 反而高于 Nord。这不是说 Nord 一定比 Tidecast 便宜,而是说「4.5 比 1.8 大」这个比较没有意义,因为分母不同。
换算之后仍然不能直接横比,因为三个「收入」的口径也不同:
| 收入口径 | 包含什么 | 不包含什么 |
|---|---|---|
| ARR | 年度经常性订阅收入 | 一次性收入、服务收入 |
| 净收入 | 扣退款、平台分成、支付费后的收入 | 未扣营销、服务器、工具 |
| 收入 | 咨询和订阅的合同收入 | 未扣退款、支付费、直接成本 |
LedgerLite 的 ARR 是「已锁定的年度经常性收入」,质量最高;Tidecast 的净收入已经扣掉渠道成本,更接近「能留下的收入」;Nord 的收入是合同金额,还没有扣退款和直接成本。三种口径都能叫「收入」,但含金量不同。比较之前至少要问:这个收入是毛的还是净的、是合同额还是已确认额、含不含一次性项目。
同一收入规模下的结构差
为了只比较结构,把三个案例都放到同一个收入规模 $240,240 上,并采用一组教学参数:
| 结构 | 收入倍数区间 | 说明 |
|---|---|---|
| 100% 经常性 | 2.5×–4.0× | 以 LedgerLite 的 3.2× 为区间中点附近的锚 |
| 0% 经常性 | 1.0×–2.0× | 以 Tidecast 的 1.8× 为区间上沿附近的锚 |
| 27.3% 经常性 | 1.409×–2.546× | 按经常性占比在两组区间之间线性插值 |
这三个区间是教学参数,不是市场报价。2.5×–4.0× 和 1.0×–2.0× 的作用是给「结构差」一个可计算的尺度;真实交易里,倍数还会被增长、毛利、集中度、买方类型和交易结构改变,这些在第 11 章展开。
按同一收入 $240,240 计算:
| 结构 | 低值 | 中值 | 高值 |
|---|---|---|---|
| 100% 经常性 | $600,600 | $780,780 | $960,960 |
| 27.3% 经常性 | $338,594 | $475,099 | $611,603 |
| 0% 经常性 | $240,240 | $360,360 | $480,480 |
中值的差距是:
经常性中值 = 240,240 × 3.25 = $780,780
一次性中值 = 240,240 × 1.50 = $360,360
中值差 = 780,780 − 360,360 = $420,420
420,420 ÷ 240,240 = 1.75,也就是 1.75× 收入。也就是说,在收入规模、毛利和其他条件都被假设相同的情况下,单是「经常性 vs 一次性」的结构差,就能让中值估值相差 1.75 倍收入。低值差是 $360,360,高值差是 $480,480;区间越宽,结构差越大。
这个计算也解释了为什么 LedgerLite 的 3.2× ARR 和 Tidecast 的 1.8× 收入会同时存在:它们分别落在各自结构的区间里。LedgerLite 的 3.2× 在 2.5×–4.0× 之内,Tidecast 的 1.8× 在 1.0×–2.0× 之内。结构不能解释全部价格,但能解释「为什么同样的收入,倍数可以差一倍」。
为什么 Nord 的 4.5× SDE 只值约 1.0× 收入
Nord Studio 是最容易被误读的案例。它的披露锚是 4.5× SDE = $154,440,按收入换算只有约 1.001×,低于线性插值给出的 1.409×–2.546× 区间。原因不在结构公式,而在 SDE 的质量:
| 项 | 金额或比例 | 含义 |
|---|---|---|
| 收入 | $154,320 | 咨询 72.7%、产品 27.3% |
| SDE | $34,320 | 已扣两人工资 $96,000 |
| SDE 利润率 | 34,320 ÷ 154,320 = 22.2% | 每美元收入只留下 22.2 美分 SDE |
| 服务收入占比 | 72.7% | 依赖两位合伙人的时间和关系 |
| 前 3 家客户 | 48% | 客户集中度较高 |
| 折价后倍数 | 3.0× SDE = $102,960 | 买方因服务依赖下调报价 |
Nord 的 SDE 利润率只有 22.2%,而 LedgerLite 是 54.2%,Tidecast 是 87.7%:
LedgerLite = 130,240 ÷ 240,240 = 54.2%
Tidecast = 121,171 ÷ 138,171 = 87.7%
Nord = 34,320 ÷ 154,320 = 22.2%
对一家利润这么薄、又依赖两位合伙人的服务生意,买方不会用收入倍数来定价,而会用 SDE 倍数;4.5× SDE 听起来高,但乘出来的绝对值只有 $154,440,换算成收入约 1.0×。折价后的 3.0× SDE 只有 $102,960,换算成收入约 0.667×。
这说明两件事。第一,倍数的高低必须和分母的绝对额一起看:4.5× 一个很小的 SDE,可能比 1.8× 一个较大的净收入更便宜。第二,结构模型只能解释「经常性占比」这一层;Nord 的低估值还来自低 SDE 利润率、合伙人人身依赖和客户集中度,这些是结构公式之外的折价因素。第 11.2 节会把增长、毛利、集中度对倍数的影响展开,见 11.2 增长、毛利、集中度对倍数的影响 。
还有一个容易忽略的时点问题:LedgerLite 的年付预收会让现金领先于收入,年末递延收入 $22,000,占 ARR 的 9.2%。买方在尽调时会把递延收入当成一项服务义务,可能要求从价格中扣除,也可能因为现金充裕而给出溢价。估值倍数用的是收入,但交易价格用的是现金和负债,两者之间的桥接见 4.1 预收、递延与确认时点 。
把估值差写成代码
下面的 valuation-gap.ts 把本节的口径固化成四个函数:blendedBand 按经常性占比混合两组倍数区间,valuationRange 把区间落到具体收入上,valuationGap 计算同一收入下两种结构的差额,impliedRevenueMultiple 把任意估值锚换算成收入倍数。所有倍数用基点,金额用整数美分。
// file: src/fin/valuation-gap.ts
// tier: L1
// verify: node --test test/fin/valuation-gap.test.ts
import { type Cents } from "../core/money.ts";
import { type Bps, applyRate, divide } from "../core/rate.ts";
import { type Result, fail, ok } from "../core/result.ts";
export type MultipleBand = {
lowBps: Bps;
highBps: Bps;
};
export type ValuationRange = {
lowBps: Bps;
midBps: Bps;
highBps: Bps;
lowCents: Cents;
midCents: Cents;
highCents: Cents;
};
export type ValuationGap = {
first: ValuationRange;
second: ValuationRange;
lowGapCents: Cents;
midGapCents: Cents;
highGapCents: Cents;
};
export const RECURRING_BAND: MultipleBand = {
lowBps: 25000,
highBps: 40000,
};
export const ONE_TIME_BAND: MultipleBand = {
lowBps: 10000,
highBps: 20000,
};
function checkBand(band: MultipleBand): string | null {
for (const value of [band.lowBps, band.highBps]) {
if (!Number.isInteger(value) || value < 0) {
return "multiple must be a non-negative integer in basis points";
}
}
if (band.lowBps > band.highBps) {
return "low multiple must not exceed high multiple";
}
return null;
}
function checkShare(shareBps: Bps): string | null {
if (!Number.isInteger(shareBps) || shareBps < 0 || shareBps > 10000) {
return "recurring share must be between 0 and 10000 bps";
}
return null;
}
function checkRevenue(revenueCents: Cents): string | null {
if (!Number.isInteger(revenueCents) || revenueCents <= 0) {
return "revenue must be a positive integer amount in cents";
}
return null;
}
/**
* Linear blend between the one-time band (0% recurring) and the recurring band
* (100% recurring). The bands are teaching parameters, not observed prices.
*/
export function blendedBand(
recurringShareBps: Bps,
recurring: MultipleBand = RECURRING_BAND,
oneTime: MultipleBand = ONE_TIME_BAND,
): Result<MultipleBand> {
const shareError = checkShare(recurringShareBps);
if (shareError) {
return fail(shareError);
}
const recurringError = checkBand(recurring);
if (recurringError) {
return fail(recurringError);
}
const oneTimeError = checkBand(oneTime);
if (oneTimeError) {
return fail(oneTimeError);
}
const low =
oneTime.lowBps +
Math.round(
((recurring.lowBps - oneTime.lowBps) * recurringShareBps) / 10000,
);
const high =
oneTime.highBps +
Math.round(
((recurring.highBps - oneTime.highBps) * recurringShareBps) / 10000,
);
return ok({ lowBps: low, highBps: high });
}
export function valuationRange(
revenueCents: Cents,
band: MultipleBand,
): Result<ValuationRange> {
const revenueError = checkRevenue(revenueCents);
if (revenueError) {
return fail(revenueError);
}
const bandError = checkBand(band);
if (bandError) {
return fail(bandError);
}
const midBps = Math.round((band.lowBps + band.highBps) / 2);
return ok({
lowBps: band.lowBps,
midBps,
highBps: band.highBps,
lowCents: applyRate(revenueCents, band.lowBps),
midCents: applyRate(revenueCents, midBps),
highCents: applyRate(revenueCents, band.highBps),
});
}
/**
* Two structures valued on the same revenue. Positive gaps mean the first
* structure is worth more; the sign is meaningful.
*/
export function valuationGap(
revenueCents: Cents,
firstShareBps: Bps,
secondShareBps: Bps,
): Result<ValuationGap> {
const firstBand = blendedBand(firstShareBps);
if (!firstBand.ok) {
return firstBand;
}
const secondBand = blendedBand(secondShareBps);
if (!secondBand.ok) {
return secondBand;
}
const first = valuationRange(revenueCents, firstBand.value);
if (!first.ok) {
return first;
}
const second = valuationRange(revenueCents, secondBand.value);
if (!second.ok) {
return second;
}
return ok({
first: first.value,
second: second.value,
lowGapCents: first.value.lowCents - second.value.lowCents,
midGapCents: first.value.midCents - second.value.midCents,
highGapCents: first.value.highCents - second.value.highCents,
});
}
/** Convert any valuation anchor into a multiple of revenue for comparison. */
export function impliedRevenueMultiple(
valuationCents: Cents,
revenueCents: Cents,
): Result<Bps> {
if (!Number.isInteger(valuationCents) || valuationCents < 0) {
return fail("valuation must be a non-negative integer amount in cents");
}
const revenueError = checkRevenue(revenueCents);
if (revenueError) {
return fail(revenueError);
}
return ok(divide(valuationCents, revenueCents));
}
代码里有三个细节。
第一,blendedBand 在「0% 经常性」和「100% 经常性」两组区间之间做线性插值。27.3% 的经常性占比对应 1.4094×–2.5458×;这不是说真实市场会精确按比例定价,而是说在只有结构信息时,线性插值是一个可复算的基准。
第二,valuationGap 的差额带符号。用 100% 经常性减去 0% 经常性,中值差是正 $420,420;反过来调用会得到负值。符号有意义,不要取绝对值之后再解释。
第三,impliedRevenueMultiple 只做除法,不做「可比公司调整」。它回答的是「这个估值相当于多少倍收入」,不回答「这个倍数是否合理」。合理性问题要回到增长、毛利、集中度和买方视角,见 11.1 三种估值口径
与 11.3 估值区间与谈判区间
。
用三个案例调用,结果是:LedgerLite 的 $768,768 ÷ $240,240 = 32000 个基点(3.2×);Tidecast 的 $248,708 ÷ $138,171 = 18000 个基点(1.8×);Nord 的 $154,440 ÷ $154,320 = 10008 个基点(约 1.001×);折价后的 Nord 是 6672 个基点(约 0.667×)。这些结果与上面的换算表一致。
小结
- 3.2× ARR、1.8× 收入、4.5× SDE 的分母不同,不能直接比较;先换算成同一分母,再谈价格。
- 换算成收入倍数后:LedgerLite 3.2×、Tidecast 1.8×、Nord 约 1.001×、折价后的 Nord 约 0.667×。
- 同一收入 $240,240 下,100% 经常性区间 2.5×–4.0×,0% 经常性区间 1.0×–2.0×,中值差 $420,420,相当于 1.75× 收入。
- 27.3% 经常性按线性插值对应 1.409×–2.546×;Nord 的实际锚低于这个区间,因为 SDE 利润率只有 22.2%,且依赖两位合伙人和前 3 家客户。
- 倍数高低必须和分母的绝对额一起看:4.5× 一个很小的 SDE,可能比 1.8× 一个较大的净收入更便宜。
- 估值倍数用收入,交易价格用现金和负债;递延收入、应收和退款准备都会改变两者之间的桥。
阅读导航:上一节:4.2 收入质量:集中度、续费、退款 · 下一节:5.1 自上而下与自下而上的预算 。
常见错误与边界
- 直接比较 3.2、1.8、4.5。 三个倍数的分母分别是 ARR、净收入和 SDE;不换分母就比大小,等于拿长度比重量。
- 把 ARR 当收入。 ARR 只含经常性收入;Nord 的咨询收入和 Tidecast 的买断收入都不在 ARR 里,用 ARR 做分母会低估或高估。
- 把净收入当标价收入。 Tidecast 的 1.8× 用的是扣退款、平台分成和支付费后的 $138,171,不是标价 $191,904;用标价收入算会低估倍数。
- 把 SDE 当净利润。 SDE 还没扣买方接手后的管理人员工资;4.5× SDE 不等于 4.5× 净利润。
- 只看倍数不看绝对值。 4.5× 一个 $34,320 的 SDE 只有 $154,440;1.8× 一个 $138,171 的净收入是 $248,708;倍数低的绝对额可能更大。
- 把教学区间当市场报价。 2.5×–4.0× 和 1.0×–2.0× 是可复算的基准,不是行业标准;真实交易会被增长、毛利、集中度和交易结构改变。
- 忽略收入口径的毛净差。 ARR、净收入、合同收入三种口径都能叫「收入」,含金量不同;比较前先问「扣了什么」。
- 忽略递延收入。 LedgerLite 年末递延 $22,000,占 ARR 9.2%;买方可能把它当服务义务从价格中扣除。
- 把结构差当全部折价。 Nord 的 4.5× SDE 只值约 1.0× 收入,除了结构,还有低 SDE 利润率、合伙人人身依赖和客户集中度。
- 忘了交易结构。 资产收购、股权收购、earn-out、托管和营运资金调整都会改变最终到手金额;本节只比较「估值 ÷ 分母」这一层。
4.3 把前两节的确认和质量翻译成价格:4.1 决定收入什么时候进入报表,4.2 决定这些收入有多可靠,4.3 决定同样规模的收入在买方眼里值多少。第 5 章回到经营本身,讨论预算怎么从收入目标倒推成本和现金需求。倍数只是估值的入口,不是估值的终点;真正的价格还要经过第 11 章的区间和第 12 章的尽调。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。