《独立开发者的商业指南·资本与退出》11.1 关停决策:继续、出售、关停

继续、出售、关停不是态度题,而是三个现值:Nord 的 SDE 34,320,继续五年按 12% 折现是 37,201 美元,出售 3.0× 税后是 77,220 美元,关停净值只有 5,114 美元。本节算出出售价格低于 6,883 美元时关停更优,并说明机会成本与终值假设如何翻转结论。

以下情境为教学假设,人物与数字不代表经核实的真实案例。

生意做到某一天,创始人会同时面对三个选项:继续做、卖掉、关掉。多数讨论停在情绪层——「再坚持一下」「有人买就卖」「不赚钱就关」。这三个答案都不能检验,因为它们没有把三个选项放到同一个时间轴上比较。继续经营拿到的是未来现金流,出售拿到的是成交价减去税,关停拿到的是资产变现减去负债和收尾成本;三者单位不同、时点不同,直接比大小没有意义。

这一节把它们折成同一个口径:现值。用 Nord Studio 的教学假设算三组数,再回答两个具体问题:出售价格低于多少时,关停反而更优?机会成本和终值假设变化时,结论会不会翻转?折现率 12%、关停耗时 6 个月、出售交割 4 个月,都是教学假设,不是对任何真实交易的预测。

三个选项,同一把尺子

先把三个选项的现金流写清楚。继续经营不是「年收入」,而是「每年留给所有者的现金」;出售不是「报价」,而是「报价减去税、再折现到今天的钱」;关停不是「省下运营费用」,而是「变现资产、清偿负债、支付收尾成本之后剩下的净额」。三者都落到「今天到手多少」这一个数上,才能比较。

选项现金口径Nord 的关键输入时点
继续未来 SDE 的现值年 SDE 34,320,扣机会成本 24,000,5 年,折现 12%第 1–5 年
出售税后成交价的现值报价 102,960(3.0× SDE),合并税率 25%第 4 个月交割
关停资产变现 − 负债 − 收尾成本现金 48,000、应收 11,264、应付 5,000、债务 25,000、收尾 24,150第 6 个月完成

继续经营的分子是 SDE,不是收入,也不是毛利。SDE 已经扣掉了两位合伙人的工资 96,000 美元(每人 48,000),所以它衡量的是「这门生意在支付了经营者和运营成本之后,还能给所有者留下多少」。这也是为什么机会成本要单独加回来:如果两位合伙人去别处工作每人能拿 60,000 美元,那么继续经营的真实代价不是「没有收入」,而是「每年少拿 24,000 美元的差额」。

出售的分子是税后所得,不是报价。Nord 的标准锚是 4.5× SDE = 154,440 美元,但买方因为服务收入占 72.7%、依赖两位合伙人,把报价下调到 3.0× SDE = 102,960 美元。按 25% 的合并税率教学假设(20% 联邦长期资本利得 + 5% 州税,与第 10.1 节同一假设),税后是 77,220 美元。这个数字才是可以和继续、关停比较的。

关停的分子是净值,不是成本。关停要退客户预付款、发通知、导出和删除数据、注销主体、支付过渡支持;同时公司还有现金、应收、应付和债务。把资产和负债放在一起,Nord 的关停净值是 5,114 美元,而不是「关停要花 24,150 美元」。这两个数字经常被混为一谈:前者是「关掉之后还剩多少」,后者是「关掉过程中要付出多少」。

Nord:三个数字

先算继续经营。Nord 的年 SDE 是 34,320 美元。两位合伙人目前各拿 48,000 美元工资;如果他们的市场工资是每人 60,000 美元,那么继续经营每年要承担 24,000 美元的机会成本。扣掉之后,继续经营每年给所有者留下的超额现金是 10,320 美元。

按 5 年、12% 折现、无终值计算,年金系数是 3.6048,继续经营的现值是:

继续经营 NPV = (34,320 − 24,000) × 3.6048 = 37,201

再算出售。3.0× SDE 的报价是 102,960 美元,25% 税后是 77,220 美元。交易在第 4 个月交割,按 12% 年折现率折回今天:

出售现值 = 77,220 ÷ 1.12^(4/12) = 74,357

最后算关停。Nord 的关停成本拆成五项:产品订阅未使用部分退款 7,020、客户通知 1,530、数据导出与删除 6,000、主体注销 3,600、过渡支持 6,000,合计 24,150 美元。资产侧有现金 48,000 美元、应收 11,264 美元;负债侧有应付 5,000 美元、个人担保的经营贷款 25,000 美元。

关停净值 = 48,000 + 11,264 − 5,000 − 25,000 − 24,150 = 5,114

关停过程约 6 个月,按中点 3 个月折现,关停现值是 4,971 美元。三个数字放在一起:继续 37,201、出售 74,357、关停 4,971。按这组假设,出售最优,继续次之,关停最差。

选项未折现折现后与出售的差
继续经营37,20137,201−37,156
出售77,22074,3570
关停5,1144,971−69,386

这张表最重要的不是「出售赢了」,而是「继续和出售的差距只有 37,156 美元」。如果把报价从 3.0× 提高到 4.5×,税后所得变成 115,830 美元,折现后 111,536 美元,差距扩大到 74,335 美元;反过来说,如果买方再压价一半,出售就未必优于继续。决策不是「卖或不卖」,而是「在什么价格上,哪个选项的现值最高」。

临界点:出售价格低于多少时关停更优

关停和出售的比较,可以写成一个不等式。设出售价格为 P,税率为 t,交割期为 m,折现率为 d,关停现值为 S。出售优于关停的条件是:

P × (1 − t) ÷ (1 + d)^(m/12) > S
P > S × (1 + d)^(m/12) ÷ (1 − t)

代入 Nord 的数字:S = 4,971,t = 25%,m = 4,d = 12%。

P* = 4,971 × 1.12^(4/12) ÷ 0.75 = 6,883

也就是说,只要出售价格高于约 6,883 美元,出售就比关停更优;低于这个价格,关停的净值更高。Nord 的 3.0× 报价是 102,960 美元,是临界点的约 15 倍,所以「卖不卖」在这个价格上不是问题,「能不能卖到这个价」才是问题。

这个临界点对输入很敏感。关停净值每减少 1,000 美元,临界点下降约 1,385 美元;税率从 25% 降到 15%,临界点降到约 6,074 美元;交割期从 4 个月拉长到 9 个月,临界点升到约 7,216 美元。临界点不是「关停值多少钱」的精确答案,而是「出售价格低到什么程度,关停才值得考虑」的数量边界。

还要注意,6,883 美元是「出售 vs 关停」的临界点,不是「出售 vs 继续」的临界点。继续经营的现值是 37,201 美元;要让出售优于继续,价格必须高于:

P* = 37,201 × 1.12^(4/12) ÷ 0.75 = 51,511

于是有三个区间:

出售价格 P最优选项理由
P < 6,883关停出售税后所得低于关停净值
6,883 ≤ P < 51,511继续继续的现值高于出售,出售又高于关停
P ≥ 51,511出售税后所得现值超过继续经营

这个三分法比「卖或不卖」有用,因为它把「价格太低」和「价格不够高」分开。6,883 美元以下,出售还不如关停;6,883 到 51,511 美元之间,出售比关停好,但不如继续做;51,511 美元以上,出售才真正优于继续。Nord 的 102,960 美元落在第三区间,所以结论是卖。

机会成本与时间价值如何改变结论

上面的结论依赖两个假设:机会成本 24,000 美元,以及继续经营没有终值。任何一个变化,结论都可能翻转。

先看机会成本。如果两位合伙人认为自己的时间不值 60,000 美元,继续经营的机会成本就是 0;这时继续经营的现值从 37,201 美元升到 123,716 美元,超过出售的 74,357 美元,最优选项从「出售」变成「继续」。反过来,如果他们的市场工资是每人 72,000 美元,机会成本变成 48,000 美元,继续经营的超额现金只剩 −13,680 美元,现值为负,出售的领先优势更大。

机会成本继续经营年超额现金继续 NPV与出售比较
034,320123,716继续胜
24,00010,32037,201出售胜
48,000−13,680−49,313出售胜

再看终值。继续经营 5 年之后,生意不会自动归零;如果第 5 年还能按 3.0× SDE 卖出,终值的现值是 102,960 ÷ 1.12^5 = 58,422 美元,继续经营的总现值变成 37,201 + 58,422 = 95,623 美元,重新超过现在的 74,357 美元。如果第 5 年只能按 1.5× 卖出,终值现值是 29,211 美元,总现值 66,412 美元,又低于现在出售。

继续总现值 = 年度超额现金 × 年金系数 + 终值 × 折现因子
终值 3.0×:37,201 + 58,422 = 95,623
终值 1.5×:37,201 + 29,211 = 66,412

这就是「时间价值改变结论」的具体含义:不是折现率高低的问题,而是「五年后还有没有人买」的问题。买方今天只愿意出 3.0×,是因为服务收入占 72.7%、依赖两位合伙人;五年后这两个条件大概率不会变好,所以用 3.0× 做终值本身就是一个乐观假设。把终值设为零,是保守口径;把终值设为 3.0×,是乐观口径。两个口径给出相反的答案,说明这笔决策的关键不是算术,而是对「五年后这门生意还值不值钱」的判断。

时间价值还有一层:交割期。出售在第 4 个月拿到钱,关停在第 6 个月完成,继续经营则是逐年拿到现金。把三者折到同一天,出售的 77,220 美元变成 74,357 美元,关停的 5,114 美元变成 4,971 美元。折现让「早拿钱」的选项占优,但出售的折现成本只有 2,863 美元,不足以改变排序;真正改变排序的是机会成本和终值,而不是折现率的小数点。

写成代码:shutdown-decision.ts

下面的 shutdown-decision.ts 把三个选项折成同一口径。annuityFactor 算继续经营的年金系数,discountFactor 算出售和关停的时点折现;continueNpvCents 先扣机会成本,再乘年金系数;shutdownNetCents 把现金、应收、应付、债务和五项收尾成本放在一起;breakEvenSalePriceCents 反解「出售等于关停」的价格。代码只做算术,不判断「五年后还有没有人买」——终值假设留在正文里,因为它是管理判断,不是公式。

// file: src/capital/shutdown-decision.ts
// tier: L1
// verify: node --test test/capital/shutdown-decision.test.ts

import { type Cents } from "../core/money.ts";
import { type Bps } from "../core/rate.ts";
import { type Result, fail, ok } from "../core/result.ts";

export type ShutdownOption = "continue" | "sell" | "shutdown";

export type ShutdownInput = {
  annualSdeCents: Cents;
  annualOpportunityCostCents: Cents;
  continueYears: number;
  discountRateBps: Bps;
  salePriceCents: Cents;
  saleTaxBps: Bps;
  saleMonths: number;
  cashCents: Cents;
  receivablesCents: Cents;
  payablesCents: Cents;
  debtCents: Cents;
  refundCents: Cents;
  notificationCents: Cents;
  dataWinddownCents: Cents;
  deregistrationCents: Cents;
  transitionCents: Cents;
  winddownMonths: number;
};

export type ShutdownOutcome = {
  continueOwnerEarningsCents: Cents;
  continueNpvCents: Cents;
  saleAfterTaxCents: Cents;
  salePresentCents: Cents;
  shutdownCostCents: Cents;
  shutdownNetCents: Cents;
  shutdownPresentCents: Cents;
  saleVsShutdownCents: Cents;
  saleVsContinueCents: Cents;
  breakEvenSalePriceCents: Cents;
  bestOption: ShutdownOption;
};

function checkAmount(value: Cents, label: string): string | null {
  if (!Number.isInteger(value) || value < 0) {
    return `${label} must be a non-negative integer amount in cents`;
  }
  return null;
}

function checkBps(value: Bps, label: string): string | null {
  if (!Number.isInteger(value) || value < 0 || value > 10000) {
    return `${label} must be between 0 and 10000 bps`;
  }
  return null;
}

function discountFactor(rateBps: Bps, months: number): number {
  return Math.pow(1 + rateBps / 10000, months / 12);
}

function annuityFactor(rateBps: Bps, years: number): number {
  if (rateBps === 0) {
    return years;
  }
  const rate = rateBps / 10000;
  let factor = 0;
  for (let year = 1; year <= years; year += 1) {
    factor += 1 / Math.pow(1 + rate, year);
  }
  return factor;
}

/**
 * Three options are compared on the same present-value basis. Continue is the
 * SDE left after charging the founders' market wage, discounted as a finite
 * annuity with no terminal value. Sell is the offer after the combined
 * capital-gains tax assumption, discounted from closing. Shutdown is cash
 * plus collectible receivables minus payables, debt and wind-down costs; a
 * negative result means the owners must fund the gap. The break-even price
 * answers the narrow question: below what offer is shutting down better
 * than selling.
 */
export function shutdownDecision(
  input: ShutdownInput,
): Result<ShutdownOutcome> {
  const sdeError = checkAmount(input.annualSdeCents, "annual SDE");
  if (sdeError) {
    return fail(sdeError);
  }
  if (input.annualSdeCents === 0) {
    return fail("annual SDE must be positive");
  }
  for (const [value, label] of [
    [input.annualOpportunityCostCents, "annual opportunity cost"],
    [input.salePriceCents, "sale price"],
    [input.cashCents, "cash"],
    [input.receivablesCents, "receivables"],
    [input.payablesCents, "payables"],
    [input.debtCents, "debt"],
    [input.refundCents, "refund"],
    [input.notificationCents, "notification"],
    [input.dataWinddownCents, "data wind-down"],
    [input.deregistrationCents, "deregistration"],
    [input.transitionCents, "transition support"],
  ] as Array<[Cents, string]>) {
    const error = checkAmount(value, label);
    if (error) {
      return fail(error);
    }
  }
  for (const [value, label] of [
    [input.discountRateBps, "discount rate"],
    [input.saleTaxBps, "sale tax"],
  ] as Array<[Bps, string]>) {
    const error = checkBps(value, label);
    if (error) {
      return fail(error);
    }
  }
  if (
    !Number.isInteger(input.continueYears) ||
    input.continueYears < 1 ||
    input.continueYears > 10
  ) {
    return fail("continue years must be an integer between 1 and 10");
  }
  for (const [value, label] of [
    [input.saleMonths, "sale months"],
    [input.winddownMonths, "wind-down months"],
  ] as Array<[number, string]>) {
    if (!Number.isInteger(value) || value < 0 || value > 24) {
      return fail(`${label} must be an integer between 0 and 24`);
    }
  }

  const continueOwnerEarningsCents = Math.max(
    0,
    input.annualSdeCents - input.annualOpportunityCostCents,
  );
  const continueNpvCents = Math.round(
    continueOwnerEarningsCents * annuityFactor(input.discountRateBps, input.continueYears),
  );

  const saleAfterTaxCents = Math.round(
    input.salePriceCents * (1 - input.saleTaxBps / 10000),
  );
  const salePresentCents = Math.round(
    saleAfterTaxCents / discountFactor(input.discountRateBps, input.saleMonths),
  );

  const shutdownCostCents =
    input.refundCents +
    input.notificationCents +
    input.dataWinddownCents +
    input.deregistrationCents +
    input.transitionCents;
  const shutdownNetCents =
    input.cashCents +
    input.receivablesCents -
    input.payablesCents -
    input.debtCents -
    shutdownCostCents;
  const shutdownPresentCents = Math.round(
    shutdownNetCents /
      discountFactor(input.discountRateBps, input.winddownMonths / 2),
  );

  const breakEvenSalePriceCents =
    shutdownPresentCents <= 0
      ? 0
      : Math.ceil(
          (shutdownPresentCents *
            discountFactor(input.discountRateBps, input.saleMonths)) /
            (1 - input.saleTaxBps / 10000),
        );

  let bestOption: ShutdownOption = "continue";
  let bestValue = continueNpvCents;
  if (salePresentCents > bestValue) {
    bestOption = "sell";
    bestValue = salePresentCents;
  }
  if (shutdownPresentCents > bestValue) {
    bestOption = "shutdown";
  }

  return ok({
    continueOwnerEarningsCents,
    continueNpvCents,
    saleAfterTaxCents,
    salePresentCents,
    shutdownCostCents,
    shutdownNetCents,
    shutdownPresentCents,
    saleVsShutdownCents: salePresentCents - shutdownPresentCents,
    saleVsContinueCents: salePresentCents - continueNpvCents,
    breakEvenSalePriceCents,
    bestOption,
  });
}

把 Nord 的数字换成美分代进去:继续经营年超额现金 1,032,000 美分,5 年年金系数 3.6048,现值 3,720,129 美分(37,201 美元);出售税后 7,722,000 美分,4 个月折现后 7,435,733 美分(74,357 美元);关停成本 2,415,000 美分,关停净值 511,400 美分(5,114 美元),3 个月折现后 497,114 美分(4,971 美元);临界点 688,337 美分(6,883 美元)。bestOption 返回 sell,因为 7,435,733 大于 3,720,129,也大于 497,114。

代码里有三个刻意的选择。第一,继续经营用「SDE 减机会成本」,而不是直接用 SDE;机会成本是继续经营的真实代价,不扣就会高估继续。第二,关停用「资产减负债减成本」,而不是「成本合计」;关停净值可能是正数,也可能是负数,符号本身是信息。第三,临界点只在关停净值为正时计算;如果关停净值为负,任何非负的出售价格都优于关停,临界点就是 0,而不是一个负数。

小结

  • 继续、出售、关停要比的是现值,不是收入、报价或成本;三者必须折到同一天。
  • Nord 的继续经营现值 37,201 美元(扣 24,000 机会成本、5 年、12%),出售现值 74,357 美元(3.0× SDE、25% 税、4 个月交割),关停现值 4,971 美元(净值 5,114、6 个月收尾)。
  • 按这组假设,出售最优,继续次之,关停最差;出售比继续多 37,156 美元,比关停多 69,386 美元。
  • 「出售 vs 关停」的临界点是 6,883 美元;低于这个价格,关停的净值更高。
  • 「出售 vs 继续」的临界点是 51,511 美元;低于这个价格,继续的现值更高。
  • 三个区间:低于 6,883 关停;6,883 到 51,511 继续;高于 51,511 出售。
  • 机会成本从 0 变到 24,000,继续经营现值从 123,716 降到 37,201,最优选项从继续翻转为出售。
  • 终值假设同样能翻转结论:5 年后按 3.0× 退出,继续总现值 95,623,重新超过现在出售;终值为零时,出售才占优。
  • 折现率影响排序的幅度,机会成本和终值影响排序的方向;先争论后者,再调前者。

阅读导航:上一节:10.3 从经营者到投资者的身份转换 · 下一节:11.2 用户、数据与订阅的收尾 。

常见错误与边界

  1. 拿报价和年收入比。 报价是资产价格,年收入是流量;要比的是税后报价的现值和未来现金流的现值。
  2. 把 SDE 当净利润。 SDE 已经扣了运营费用和合伙人工资,但没有扣机会成本、税和资本开支;继续经营的分子要先扣机会成本。
  3. 把关停成本当关停净值。 成本是「关掉要付出多少」,净值是「关掉之后还剩多少」;Nord 的成本 24,150,净值 5,114,两者符号都可能不同。
  4. 忽略个人担保。 关停净值算的是公司口径;如果债务有个人担保,负数部分会回到合伙人身上,见 11.3。
  5. 用同一个折现率折所有选项。 继续经营是多年现金流,出售是单笔交割,关停是半年内的分批收支;时点不同,折现因子也不同。
  6. 忘记机会成本。 两位合伙人各拿 48,000 工资,不代表他们的时间只值 48,000;市场工资与现工资的差额才是继续经营的真实代价。
  7. 假设终值一定存在。 五年后有没有人按 3.0× 买,取决于那时的服务占比和合伙人依赖;把终值设为零是保守口径,设为 3.0× 是乐观口径。
  8. 把临界点当精确答案。 6,883 美元依赖税率、交割期、折现率和关停成本;输入变 10%,临界点也会变。
  9. 只算一次,不算区间。 出售价格、关停成本、机会成本都是区间;用三个区间做敏感性,比用一个点做结论可靠。
  10. 把「继续」当成不花钱。 继续经营要投入合伙人的时间、维持客户关系和承担收入波动的风险;这些都是成本,只是不在利润表上。

本节的边界是「三个选项的现值比较」:只覆盖继续经营的年金、出售的税后所得、关停的净值、临界点和机会成本,不展开买方报价的形成、税种差异、合伙人的个人担保和合同终止条款。所有折现率、税率、机会成本、关停成本和交割期都是教学假设;具体交易的价格与条款以合同为准,本节不构成投资、税务或法律意见。买方为什么压价见 4.2 买方如何看独立开发者资产 ;税后所得与再投资见 10.1 税后所得与分期 。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「books」更多文章

  1. 《移动游戏产品的架构·商业化与发行工程》附录 C 商业化与发行评审清单
  2. 《移动游戏产品的架构·商业化与发行工程》附录 B 双案例商业化事实表
  3. 《移动游戏产品的架构·商业化与发行工程》附录 A 商业化与发行术语速查