lyndonkl/claude/special-situation-models

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Values companies the standard DCF cannot handle, across five branches — distress (failure probability from a bond price or rating, blended with the distress-sale outcome), financial service firms (equity excess return and FCFE against regulatory capital, since a bank gets no FCFF and no optimal debt ratio), private companies (total beta for an undiversified owner, Silber and bid-ask illiquidity discounts), cyclical and commodity firms (mid-cycle normalized earnings), and young negative-earnings firms (a revenue and margin path plus survival odds, emitted as a dcf-valuation-engine payload). Also walks a private owner's value to an IPO offer price line by line. Use when valuing a bank, insurer, startup, distressed firm, private business, miner or deep cyclical, when pricing an IPO or a sale to a public buyer, or when asked about probability of distress, total beta, illiquidity discount, excess return models, normalized earnings, or negative-earnings valuation.

Install

npx vskill@latest install lyndonkl/claude/special-situation-models

SKILL.md

Special situation models

A standard discounted cash flow model assumes a lot. It assumes the firm survives to reach stable growth, that its debt is a financing choice, that its owner is diversified, that this year's earnings say something about a normal year, and that there are earnings at all.

Five kinds of company break one of those assumptions. This skill repairs the specific break. It does not replace the DCF, and for four of the five branches the answer still runs through dcf-valuation-engine.

Which branch applies

Answer this before running anything. The branch is a judgment about the company, and the script does not guess it for you.

The company isBranchSubcommand
At real risk of not surviving — high leverage, marginal operating income, a declining business1. Distressdistress
A bank, an insurer, or any firm whose raw material is money2. Financial serviceexcess-return
Not publicly traded, and the buyer cannot diversify3. Private companyprivate
At a point in a cycle, or driven by a commodity price4. Cyclical or commoditycyclical
Young, growing fast, and losing money5. Young companyyoung-company

More than one can apply. A young company usually needs branch 5 and branch 1 together. A private cyclical needs 3 and 4. Run them in the order above, because each later branch consumes the output of the earlier one.

One transition sits alongside the five: a private company on its way to a public listing, or to a sale to a listed buyer. That is the ipo subcommand, and it consumes branch 3.

What each branch forbids

This is the part that gets skipped, and it is where the damage happens.

A bank gets no FCFF valuation and no optimal-debt-ratio analysis. For an industrial firm, debt is a source of capital, so you can separate operating from financing decisions. For a bank, debt is raw material. Deposits are the input the business transforms into loans. There is no meaningful firm value and no meaningful cost of capital, so do not run dcf-valuation-engine value on a bank, and do not run cost-of-capital-toolkit debt-schedule on one. Regulatory capital governs the financing mix, not a tax-shield calculation. A bank that breaches its capital ratio can be taken over and closed however good its earnings look.

Distress risk does not belong in the discount rate. Raise the rate and probability-weight the value and you have counted the same risk twice. Pick the probability weight.

A total beta does not belong in a valuation for a diversified buyer. It systematically undervalues the business and hands the surplus to the buyer. The same applies to the illiquidity discount: a listed acquirer's own shareholders can sell, so no discount applies.

A trailing return on equity does not survive re-regulation. If the regulator is about to demand more capital, the return earned on the old base is not the sustainable one.

Normalized earnings and a recovery in growth are the same recovery. Normalize the base year or forecast the recovery, not both.

A young company with no failure branch is not a valuation. Roughly two-thirds of startups are gone within seven years, and the value of the survivors is not the value of the population.

The script

resources/special.py — pure standard library, no installation needed. Every subcommand takes JSON on stdin (or --in FILE) and prints JSON.

bash
python3 resources/special.py <subcommand> --example # show the input shape
python3 resources/special.py <subcommand> --in payload.json
python3 resources/special.py selftest # verify the engine
SubcommandTurns thisInto this
distressa traded bond price, or a ratingannual and cumulative probability of failure, and the two-branch blend
excess-returnbook equity, a return-on-equity path, a capital pathbank equity value, per share, both by residual income and by FCFE
privatea market beta with its R-squared, revenues, profitabilitytotal beta, cost of equity, three illiquidity discounts
ipoa private value, the offering terms and the cap tablethe bridge from private value to offer price, step by step
cyclicalan earnings history, or a commodity price linkmid-cycle operating income, revenues at today's price
young-companya revenue target and a margin targeta full dcf.py value payload plus survival odds

Run selftest after editing anything. It reproduces the source models to nine decimals and checks identities that a wrong port would break. Every case it runs is written up in resources/worked-examples.md, with the payload alongside the answer.

1. Distress adjustment

A going-concern model prices only the branch where the firm lives. The repair is an explicit probability-weighted blend of two outcomes.

value = going-concern value × (1 − p) + distress-sale value × p
Getting the probability

Five sources, in increasing order of information content. Pass whichever you have.

InputSource
bondthe market price of the firm's own traded bond — the sharpest and usually the most pessimistic
ratingthe cumulative ten-year default rate for that rating class
sector_survivallong-run survival statistics, for a firm with no debt to price
annual_probabilityyour own estimate, stated per year
cumulative_probabilityyour own estimate, stated over the horizon

The bond route prices the promised coupons and principal, weights each by the probability the firm survives to pay it, and discounts at the riskfree rate. All the credit risk sits in the survival weights. Discounting at the bond's own yield instead would count it twice.

bash
echo '{"bond": {"coupon_rate": 0.06375, "maturity_years": 7,
"riskfree_rate": 0.03, "market_price": 529},
"horizon_years": 10, "going_concern_value": 8.12,
"distress": {"basis": "explicit", "proceeds": 2769,
"debt_face_value": 11000}}' \
| python3 resources/special.py distress

Two modelling assumptions are baked in: recovery in distress is zero, and discounting is at the riskfree rate. Both are choices. Assuming a positive recovery would lower the implied probability for the same price.

Report the cumulative probability over your forecast horizon, not the annual one. For Las Vegas Sands the difference between 13.54% a year and 76.66% over ten years is the difference between a $7 stock and a $2 stock.

Getting the distress-sale value

Set distress.basis:

  • book — proceeds are a percentage of book equity plus book debt. The default recovery is

50%. Cut it when the economy is weak and every peer is selling the same assets at once.

  • going_concern — proceeds are a percentage of the going-concern value, for a firm that

would be sold intact rather than broken up.

  • explicit — you have an estimate of what the assets would fetch.

Add debt_face_value when you are valuing equity. Equity in distress is a residual: if proceeds fall short of what lenders are owed, shareholders get nothing.

The partial wipeout

A bailout can save the firm and destroy the equity. Set equity_loss_fraction instead of a distress branch, and the blend becomes a single haircut:

adjusted value = going-concern value × (1 − probability × loss fraction)

Boeing in March 2020: a 20% failure probability with a 50% loss to equity is a 10% haircut, not a 20% one.

Where the number goes

dcf-valuation-engine already has a failure block that does the simple blend. Feed it the cumulative probability from here. Use this subcommand's own blend when equity is a residual against the face value of debt, or when the case is a partial wipeout — neither of those fits in the DCF engine's block.

2. Financial service firms

Value the equity directly. See resources/financial-service-firms.md for the full argument and for the choice among the three equity models.

value of equity = current book equity + PV of (return on equity − cost of equity) × book equity

Book value is close to irrelevant for an industrial firm. For a bank it is the opposite: assets are marked to market, and regulatory ratios are computed on book equity. That gives a bank a hard definition of reinvestment, which industrial firms lack.

Two reinvestment modes:

`retention` — book equity grows by retained earnings. This is the standard equity excess return model. Give a high-growth return on equity, a retention or payout ratio, and a stable block. Each driver fades to its stable value over the second half of the horizon unless you set fade_second_half: false.

`regulatory_capital` — book equity is whatever the capital ratio requires. Give the risk-adjusted assets, their growth rate, and the path of the Tier 1 or CET1 ratio. Use this when ratios are moving or the bank is in crisis. Book equity often sits above regulatory capital, so pass required_book_equity as a year-by-year list instead when the bank has disclosed the path. Subtract any one-off hit to capital, such as a fine, with one_off_capital_hit.

bash
echo '{"book_equity": 64609, "forecast_years": 10,
"reinvestment": "regulatory_capital",
"regulatory_capital": {"risk_adjusted_assets": 445570, "asset_growth": 0.01,
"capital_ratio": {"start": 0.1241, "end": 0.1567,
"converge_by": 10}},
"return_on_equity": {"start": -0.137, "end": 0.0944, "converge_by": 10},
"cost_of_equity": 0.102, "shares_outstanding": 1386,
"probability_of_equity_wipeout": 0.10,
"stable": {"return_on_equity": 0.0944, "growth_rate": 0.01,
"cost_of_equity": 0.0944}}' \
| python3 resources/special.py excess-return
Reading the output

value_of_equity and value_of_equity_via_fcfe should match, and route_difference should be near zero. Residual income and discounted free cash flow to equity are the same model written two ways. A gap means the book-equity rollforward disagrees with the cash flows, which is the classic bank-model error.

Early fcfe is deeply negative for a bank rebuilding capital. That is correct, not a bug. Every increase in the capital ratio is reinvestment and it comes out of shareholder cash flow.

Three inputs carry the answer. Set the sustainable return on equity, not the trailing one. Anchor the terminal return on equity on the cost of equity unless a franchise justifies more. Anchor the target capital ratio on the peer distribution rather than the regulatory minimum.

3. Private company adjustments

Two separate repairs, and the script runs both. Detail in resources/private-company-adjustments.md.

Total beta, for an owner who holds nothing else:

total beta = market beta / correlation with the market
correlation = square root of the average R-squared of the comparables' regressions

The square root is not optional. R-squared is a share of variance and betas are built from standard deviations. Dividing a 1.18 beta by an R-squared of 0.25 gives 4.72; dividing by the correlation of 0.50 gives 2.36.

An illiquidity discount, applied to equity value after the DCF:

bash
echo '{"buyer": "private",
"cost_of_equity": {"unlevered_market_beta": 1.18, "r_squared": 0.25,
"debt_equity_ratio": 0.1433, "tax_rate": 0.40,
"riskfree_rate": 0.0425, "equity_risk_premium": 0.04},
"illiquidity": {"revenues_millions": 1.2, "positive_earnings": true,
"cash_to_firm_value": 0.05},
"equity_value": 520990}' \
| python3 resources/special.py private

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 95 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
162
Repository forks
24
7-day trend score
25

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/lyndonkl/claude/special-situation-models/badge)](https://verified-skill.com/skills/lyndonkl/claude/special-situation-models)

Something wrong with this skill or its page? Tell us.