
Company Valuation
- 1.6k installs
- 3.1k repo stars
- Updated July 21, 2026
- himself65/finance-skills
company-valuation is a financial analysis skill that pulls public company data via yfinance and builds DCF, peer-multiple, and sum-of-parts models so developers who need defensible fair-value estimates can triangulate an
About
company-valuation is a finance-skills module that estimates intrinsic value for any public company using three proven methods. It pulls 5 years of financials and analyst estimates through yfinance, builds a 5-year DCF with explicit revenue, margin, WACC, and terminal-value assumptions, and applies peer median P/E, EV/Revenue, and EV/EBITDA multiples across 4–6 peers. When a company reports 2 or more segments, the skill runs sum-of-parts (SOTP) analysis. Output includes a blended implied price with method weights, a WACC × g sensitivity matrix, and Bull, Base, and Bear scenarios, with edge-case handling for banks, REITs, pre-revenue, and cyclical names. Developers reach for it during equity research, model checks, or investment memo drafting.
- Pulls 5 years of financials plus analyst estimates via yfinance
- Builds a full 5-year DCF model with revenue, margin, WACC and terminal value assumptions
- Runs peer-median relative valuation across 4-6 comparable companies
- Executes sum-of-parts (SOTP) analysis for multi-segment businesses
- Delivers a triangulated implied share price with Bull/Base/Bear scenarios and sensitivity tables
Company Valuation by the numbers
- 1,550 all-time installs (skills.sh)
- +137 installs in the week ending Aug 5, 2026 (Skillselion tracking)
- Ranked #93 of 1,106 Finance & Trading skills by installs in the Skillselion catalog
- Security screen: MEDIUM risk (skills.sh audit)
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/himself65/finance-skills --skill company-valuationAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1.6k |
|---|---|
| repo stars | ★ 3.1k |
| Security audit | 2 / 3 scanners passed |
| Last updated | July 21, 2026 |
| Repository | himself65/finance-skills ↗ |
How do you estimate fair value for a public company?
Quickly estimate the fair value of any public company using multiple proven financial methods.
Who is it for?
Developers and analysts building repeatable equity valuation workflows who want DCF, multiples, and SOTP triangulation from yfinance data.
Skip if: Teams valuing private companies without public filings or anyone needing live trading execution rather than research-grade price estimates.
When should I use this skill?
User asks for DCF valuation, peer multiples, sum-of-parts analysis, implied share price, or fair value of a public ticker.
What you get
DCF model, peer multiple table, optional SOTP breakdown, blended implied price, and WACC sensitivity matrix
- Blended implied share price report
- WACC sensitivity matrix
By the numbers
- Pulls 5 years of financials and analyst estimates via yfinance
- Applies peer multiples across 4–6 comparable companies
- Runs sum-of-parts when the company has 2 or more reporting segments
Files
Company Valuation
Triangulates intrinsic value via three methods, then blends them to an implied share price:
1. DCF — 5-year FCFF projection, discount at WACC, terminal value. 2. Relative — apply peer median P/E, EV/Revenue, EV/EBITDA. 3. SOTP — when 2+ distinct reporting segments exist, value each at pure-play peer multiples.
Always present a WACC × terminal-growth sensitivity table and Bull/Base/Bear scenarios.
Disclaimer: Research/educational output. Not financial advice.
---
Step 1: Detection Flow
Detect data source and runtime deps. The skill supports 3 method paths — pick the richest one available.
Environment status:
!`python3 -c "import yfinance, numpy, pandas; print('YFIN_OK')" 2>/dev/null || echo "YFIN_MISSING"`!`(command -v funda && funda --version) 2>/dev/null || echo "FUNDA_CLI_MISSING"`!`python3 -c "import yfinance as yf; t=yf.Ticker('^TNX'); p=t.fast_info.last_price; print(f'RF_10Y={p/100:.4f}')" 2>/dev/null || echo "RF_FETCH_FAIL"`Decision tree:
| Condition | Method path |
|---|---|
YFIN_OK | Path A (primary): yfinance for financials + peer multiples |
YFIN_MISSING but FUNDA_CLI_MISSING is not set | Path B: delegate to finance-data-providers:funda-data skill for fundamentals |
| Both missing | Path C: pip-install yfinance, then Path A. python3 -m pip install -q yfinance numpy pandas |
RF_FETCH_FAIL | Use default rf = 0.045 and note stale risk-free rate in output |
If RF_10Y= printed, use that value as rf in Step 4d instead of the hardcoded 4.5%.
---
Step 2: Choose Methods & Set Defaults
Method applicability
| Company type | DCF | Relative | SOTP | Fallback |
|---|---|---|---|---|
| Mature cash-flow (CPG, telecom, utilities) | ✅ primary | ✅ | ❌ | — |
| High-growth SaaS / software | ✅ with care | ✅ primary | ❌ | Use EV/Revenue + Rule of 40 |
| Multi-segment conglomerate | ✅ | ✅ | ✅ primary | See references/sotp.md |
| Banks / insurance | ❌ | ✅ (P/B, P/TBV) | ❌ | DDM or excess return; note in output |
| Pre-revenue | ❌ | EV/Revenue only | ❌ | Flag low confidence |
| REITs | ❌ | ✅ (P/FFO, P/AFFO) | ❌ | NAV-based |
| Cyclicals (energy, semis, industrials) | ✅ on mid-cycle | ✅ | sometimes | Normalize through-cycle |
Defaults table
Every parameter below MUST have a value before moving to Step 3. Use these unless the user overrides.
| Parameter | Default | Rationale |
|---|---|---|
| Projection horizon | 5 years | Standard explicit forecast window |
Terminal growth g | 2.5% | ~ long-run US GDP |
Risk-free rate rf | Live 10Y UST from Step 1, else 4.5% | Current cost of capital anchor |
Equity risk premium erp | 5.5% | Damodaran mid-range |
| Beta | info['beta'] from yfinance | Market-observed levered beta |
Cost of debt kd | interest_expense / total_debt, else 5.5% | Effective rate; fallback to IG spread |
| Tax rate | 3-yr median effective rate, floored 15%, capped 30% | Strips out one-offs |
| Margin assumptions | 3-yr median of each ratio | Smooths cyclical noise |
| SBC treatment | Cash for software/SaaS; non-cash for industrials/CPG | Industry convention |
| Peer count | 4-6 | Balances signal vs noise |
| Peer multiple | Median (not mean) | Robust to outliers |
| Method weights (no SOTP) | DCF 50% / Relative 50% | Equal triangulation |
| Method weights (with SOTP) | DCF 40% / Relative 30% / SOTP 30% | SOTP gets weight when applicable |
| Sensitivity grid | WACC ±1% in 0.5% steps × g from 1.5-3.5% in 0.5% | 5×5 matrix |
See references/wacc_erp_rates.md for current risk-free rates, ERP tables, and sector WACC benchmarks.
---
Step 3: Pull Data
import yfinance as yf
import numpy as np
import pandas as pd
TICKER = "AAPL" # replace
t = yf.Ticker(TICKER)
info = t.info
income_a = t.income_stmt
cashflow_a = t.cashflow
balance_a = t.balance_sheet
income_q = t.quarterly_income_stmt
cashflow_q = t.quarterly_cashflow
earnings_est = t.earnings_estimate
revenue_est = t.revenue_estimate
price = info.get("currentPrice") or info.get("regularMarketPrice")
market_cap = info.get("marketCap")
shares_out = info.get("sharesOutstanding")
total_debt = info.get("totalDebt") or 0
cash = info.get("totalCash") or 0
beta = info.get("beta") or 1.0
sector = info.get("sector")
industry = info.get("industry")Key financial statement rows (yfinance labels):
| Need | Row |
|---|---|
| Revenue | Total Revenue |
| EBIT | Operating Income |
| Net income | Net Income |
| D&A | Depreciation And Amortization (in cashflow) |
| CapEx | Capital Expenditure (negative) |
| ΔNWC | Change In Working Capital (cashflow) |
| SBC | Stock Based Compensation (cashflow) |
---
Step 4: DCF Build
Full methodology + industry-specific tweaks in references/dcf.md. Quick skeleton:
# 4a. Revenue growth path — fade from Y1 (consensus or hist CAGR) to terminal g
hist_cagr = (rev[-1] / rev[0]) ** (1 / (len(rev)-1)) - 1
y1 = float(revenue_est.loc["+1y", "growth"]) if "+1y" in revenue_est.index else hist_cagr
g_terminal = 0.025
growth_path = np.linspace(y1, g_terminal + 0.01, 5)
# 4b. Margins — 3y median
ebit_margin = float((income_a.loc["Operating Income"] / income_a.loc["Total Revenue"]).iloc[:3].median())
da_pct = float((cashflow_a.loc["Depreciation And Amortization"] / income_a.loc["Total Revenue"]).iloc[:3].median())
capex_pct = float((cashflow_a.loc["Capital Expenditure"].abs() / income_a.loc["Total Revenue"]).iloc[:3].median())
nwc_pct = float((cashflow_a.loc["Change In Working Capital"].abs() / income_a.loc["Total Revenue"]).iloc[:3].median())
tax_rate = max(0.15, min(0.30, 0.21)) # use effective if available
# 4c. FCFF per year
rev_t = [float(income_a.loc["Total Revenue"].iloc[0])]
fcff = []
for g in growth_path:
rev_t.append(rev_t[-1] * (1 + g))
ebit = rev_t[-1] * ebit_margin
nopat = ebit * (1 - tax_rate)
fcff.append(nopat + rev_t[-1]*da_pct - rev_t[-1]*capex_pct - rev_t[-1]*nwc_pct)
# 4d. WACC
rf, erp, kd = 0.045, 0.055, 0.055 # override rf with live value from Step 1
ke = rf + beta * erp
e_v = market_cap / (market_cap + total_debt)
d_v = 1 - e_v
wacc = e_v*ke + d_v*kd*(1 - tax_rate)
# 4e. Terminal value — compute both, use midpoint
tv_gordon = fcff[-1] * (1 + g_terminal) / (wacc - g_terminal)
tv_exit = (rev_t[-1] * ebit_margin + rev_t[-1] * da_pct) * 15 # peer median EV/EBITDA
tv_base = 0.5 * (tv_gordon + tv_exit)
# 4f. Bridge to equity
pv_fcff = sum(f / (1+wacc)**(i+1) for i, f in enumerate(fcff))
pv_tv = tv_base / (1+wacc)**5
ev = pv_fcff + pv_tv
equity = ev + cash - total_debt
implied_price_dcf = equity / shares_outGates: (a) if wacc <= g_terminal → stop, g too aggressive; (b) if pv_tv / ev > 0.85 or < 0.45 → flag and show both TV methods; (c) if wacc is outside the sector sanity band in references/wacc_erp_rates.md → note.
---
Step 5: Relative Valuation
Select 4-6 peers. Peer map and adjustment rules in references/relative_valuation.md.
PEERS = ["MSFT", "ORCL", "CRM", "NOW", "SAP", "WDAY"] # pick by industry
multiples = {}
for p in PEERS:
pi = yf.Ticker(p).info
multiples[p] = {
"pe_fwd": pi.get("forwardPE"),
"ev_rev": pi.get("enterpriseToRevenue"),
"ev_ebitda": pi.get("enterpriseToEbitda"),
"ps": pi.get("priceToSalesTrailing12Months"),
}
med_pe = np.nanmedian([v["pe_fwd"] for v in multiples.values()])
med_ev_rev = np.nanmedian([v["ev_rev"] for v in multiples.values()])
med_ev_eb = np.nanmedian([v["ev_ebitda"] for v in multiples.values()])
eps_ttm = float(income_q.loc["Diluted EPS"].iloc[:4].sum())
rev_ttm = float(income_q.loc["Total Revenue"].iloc[:4].sum())
ebitda_ttm = float(income_q.loc["EBIT"].iloc[:4].sum()) + float(cashflow_q.loc["Depreciation And Amortization"].iloc[:4].sum())
net_debt = total_debt - cash
implied_pe = med_pe * eps_ttm
implied_ev_rev = (med_ev_rev * rev_ttm - net_debt) / shares_out
implied_ev_ebit = (med_ev_eb * ebitda_ttm - net_debt) / shares_out
implied_price_rel = np.nanmedian([implied_pe, implied_ev_rev, implied_ev_ebit])Adjust peer median ±10-30% if target's growth or margin profile diverges materially. Always state the adjustment and reason. Rule of 40 anchor for SaaS in references/relative_valuation.md.
---
Step 6: SOTP (multi-segment only)
Skip unless the 10-K reports 2+ operating segments with distinct economics. yfinance does NOT expose segment data — user must supply or parse from filings. Full methodology in references/sotp.md:
- Identify segments + pure-play peer for each
- Apply peer median EV/EBITDA (or EV/Rev for growth segments)
- Subtract unallocated corporate costs (cap 2-5% of revenue if unknown)
- Subtract net debt, minority interest; divide by shares
SOTP discount = (SOTP price − market price) / SOTP price. Flag if >20% (conglomerate discount).
---
Step 7: Triangulate, Sensitivity, Scenarios
# Blended implied price
if sotp_price is None:
blended = 0.5*implied_price_dcf + 0.5*implied_price_rel
else:
blended = 0.4*implied_price_dcf + 0.3*implied_price_rel + 0.3*sotp_price
# 5x5 sensitivity grid
wacc_grid = [wacc + dx for dx in (-0.01, -0.005, 0, 0.005, 0.01)]
g_grid = [0.015, 0.020, 0.025, 0.030, 0.035]
sens = {}
for w in wacc_grid:
for g in g_grid:
tv = fcff[-1]*(1+g)/(w-g)
pv = sum(f/(1+w)**(i+1) for i,f in enumerate(fcff)) + tv/(1+w)**5
sens[(w,g)] = (pv + cash - total_debt) / shares_outAlso produce Bull / Base / Bear: shift revenue growth ±300bps, EBIT margin ±200bps, WACC ∓100bps, terminal g 3.0% / 2.5% / 1.5%.
---
Step 8: Respond to the User
Output in this order:
1. Headline verdict — one sentence: blended fair value, vs. current, % upside/downside, most bullish/bearish method. Example: "AAPL fair value ≈ $215 (blended), vs. current $198 → ~9% upside; DCF is most bullish at $228." 2. Snapshot — sector, industry, market cap, current price, 3M / 12M price change, LTM revenue growth. 3. Three-method summary — 3-column table: method | implied price | weight | brief rationale. 4. DCF build — assumptions table (growth path, margins, WACC components, terminal method) + 5-yr FCFF projection table + EV-to-equity bridge. 5. Peer comparison — table of peers with P/E fwd, EV/Rev, EV/EBITDA, gross margin, rev growth; bottom row = median; flag target's premium/discount. 6. SOTP (if applicable) — segment table + adjustments + equity value. 7. Sensitivity matrix — WACC × g grid (5×5), base case highlighted. 8. Scenarios — Bull / Base / Bear table with levers + implied price. 9. Key risks — 3-5 bullets: which assumption moves the answer most; what could break the thesis.
Error handling
| Missing / edge case | Action |
|---|---|
yfinance returns None for beta | Use sector-default beta from references/wacc_erp_rates.md |
| Negative LTM EBITDA | Skip EV/EBITDA multiple; rely on EV/Revenue + DCF |
| Negative LTM EPS | Skip P/E multiple; use forward P/E if positive, else skip |
| Growth > WACC in Gordon | Cap g = wacc − 0.5% and flag |
| Fewer than 3 years history | Use what's available; flag data confidence as "low" |
| Peer data fetch fails | Drop that peer from median; note in output |
| No segment data for SOTP | Skip Section 6; proceed with DCF + Relative only |
Caveats to include
- TTM data lags real-time; peer multiples reflect market sentiment (can overshoot)
- DCF is garbage-in/garbage-out; sensitivity matters more than a point estimate
- yfinance data is unofficial; cross-check any decision with primary filings
- Not financial advice
---
Reference Files
references/dcf.md— DCF methodology + industry-specific guidance (software, retail, financials, healthcare, energy, manufacturing, CPG, telecom, REITs, streaming)references/relative_valuation.md— Peer selection, multiple adjustment rules, Rule of 40, peer sets by themereferences/sotp.md— Sum-of-parts methodology, conglomerate discount detection, catalystsreferences/wacc_erp_rates.md— Risk-free rates, equity risk premiums, sector WACC benchmarks, sector-default betas
Company Valuation
Estimate the intrinsic value of a public company via DCF, relative (peer multiple), and sum-of-parts (SOTP) methods, and blend into a triangulated implied share price with sensitivity tables.
What it does
- Pulls 5 years of financials + analyst estimates via yfinance
- Builds a 5-year DCF with explicit revenue / margin / WACC / terminal-value assumptions
- Applies peer median P/E, EV/Revenue, EV/EBITDA multiples across 4-6 peers
- Runs SOTP when the company has 2+ distinct reporting segments
- Presents a blended implied price with method weights, WACC × g sensitivity matrix, and Bull/Base/Bear scenarios
- Handles banks/REITs/pre-revenue/cyclical edge cases with appropriate fallbacks
Triggers
what is AAPL worth, valuation of NVDA, fair value of TSLA, DCF for MSFT, build a DCF, intrinsic value, implied share price, is X overvalued/undervalued, relative valuation, EV/EBITDA target, SOTP, sum of the parts, price target from fundamentals, value this company
Prerequisites
- Python 3.8+
yfinance,numpy,pandas(auto-installed if missing)
Optional: finance-data-providers:funda-data skill as a fallback data source.
Platform
CLI-based agents (Claude Code). Requires shell + pip.
Setup
No authentication required. First run will auto-install dependencies.
Reference Files
references/dcf.md— DCF methodology, industry-specific guidance (software, retail, financials, healthcare, energy, manufacturing, CPG, telecom, REITs, streaming), common pitfallsreferences/relative_valuation.md— Peer selection heuristics, multiple adjustment rules, Rule of 40 for SaaS, default peer sets by themereferences/sotp.md— Sum-of-parts methodology, conglomerate discount detection, catalyst framework, position sizingreferences/wacc_erp_rates.md— Risk-free rates (live + default), equity risk premiums, sector WACC bands, sector-default betas, terminal growth ceilings
Output
Structured briefing with: headline verdict, snapshot, three-method summary, DCF build, peer comparison, SOTP (if applicable), sensitivity matrix, scenarios, key risks, and caveats.
Disclaimer
For research and educational purposes only. Not financial advice.
DCF Methodology — Detailed Reference
Expands on the summary in SKILL.md. Use this when building the DCF build table or when the user asks for industry-specific treatment.
When DCF Is Appropriate
Good fit:
- Mature companies with predictable cash flows
- Companies whose revenue and margin trajectory can be estimated within a reasonable confidence band
- Strategic valuations requiring intrinsic value assessment
- Cross-checking a relative valuation
Poor fit:
- Pre-revenue / early-stage (no cash flow history)
- Banks, insurance (use DDM or excess return model)
- REITs (use NAV)
- Highly cyclical businesses without a clear cycle baseline — use mid-cycle earnings instead
Projection Model (5-Year Explicit Forecast)
Revenue projection
1. Compute historical 3–5 year CAGR. 2. Pull analyst consensus from yfinance.Ticker.revenue_estimate. 3. Consider industry growth, competitive position, and company guidance. 4. Project revenue for Y1–Y5, fading linearly toward terminal growth rate.
Revenue_t = Revenue_{t-1} × (1 + g_t)EBIT and Free Cash Flow Build
Revenue
- COGS → historical gross margin trend
= Gross Profit
- SG&A → historical SG&A % of revenue
- R&D → historical R&D % of revenue
- Other OpEx
= EBIT (Operating Income)
FCFF = EBIT × (1 − Tax Rate)
+ Depreciation & Amortization
+ Stock-Based Compensation ← only if treating SBC as non-cash
− Capital Expenditures
− Change in Net Working CapitalAssumption checklist (state explicitly)
| Assumption | How to derive | Typical range |
|---|---|---|
| Tax rate | Effective tax rate from historicals | 15–25% US; use statutory if unreliable |
| D&A | % of revenue or PP&E schedule | 3–8% revenue for most; 15–25% for telecom/utilities |
| CapEx | % of revenue; split maintenance vs growth if possible | 3–8% SaaS; 8–15% industrials; 15–25% telecom |
| NWC change | Days sales outstanding, DPO, days inventory | Usually 1–3% of Δrevenue |
| SBC treatment | Cash for software/SaaS, non-cash for industrials/CPG | Decide upfront and disclose |
WACC Calculation
WACC = (E/V) × Ke + (D/V) × Kd × (1 − Tax Rate)Cost of Equity (CAPM)
Ke = Risk-Free Rate + Beta × Equity Risk Premium + Size Premium (if applicable)| Component | Source | Typical range |
|---|---|---|
| Risk-free rate | 10-year US Treasury | 3.5–5.0% (use current) |
| Equity risk premium | Damodaran or Duff & Phelps | 4.5–6.0% |
| Beta | yfinance info['beta'] (levered) | 0.6–2.0 |
| Size premium | Add for small/mid-cap | 0–3% |
Cost of Debt
- Preferred: interest expense / total debt from financials.
- Fallback: credit rating spread over risk-free rate.
- Investment-grade: 4–6%. High-yield: 7–10%.
Capital structure
Use market values:
- E = market cap
- D = total debt (balance sheet)
- V = E + D
Terminal Value
Method 1: Perpetuity Growth (Gordon Growth)
TV = FCFF_5 × (1 + g) / (WACC − g)- Terminal growth
g: 2–3% typical; must not exceed long-term GDP (~2.5% US, ~3–4% EM). - TV normally represents 60–80% of total EV. Flag if outside that range.
Method 2: Exit Multiple
TV = EBITDA_5 × exit EV/EBITDA multiple- Use current peer trading multiples as reference.
- Apply discount for growth deceleration by Y5.
- Cross-check against Gordon TV — if they diverge by >30%, reconcile assumptions.
Bridge to Equity Value
PV of FCFF = Σ FCFF_t / (1 + WACC)^t for t = 1..5
PV of TV = TV / (1 + WACC)^5
Enterprise Value = PV of FCFF + PV of TV
+ Cash & equivalents
− Total debt
− Minority interest
− Preferred stock
+ Equity investments (if material)
= Equity Value
Implied share price = Equity Value / diluted shares outstandingSensitivity & Scenarios
WACC × Terminal Growth matrix
5×5 grid. Vary WACC by ±1% in 0.5% steps and g by 0.5% from 1.5% to 3.5%. Highlight base case.
Scenario analysis
| Scenario | Levers |
|---|---|
| Bull | Higher revenue growth, margin expansion, lower WACC |
| Base | Median historicals / consensus |
| Bear | Revenue deceleration, margin compression, higher WACC |
Industry-Specific Guidance
Technology / SaaS
- EV/Revenue often more meaningful than P/E if not yet profitable.
- Key metrics: ARR growth, net dollar retention (NRR), Rule of 40 (growth% + FCF margin ≥ 40).
- CapEx light (3–8% rev); R&D heavy (15–30%).
- SBC material — decide cash vs non-cash upfront and disclose.
- Terminal growth: 3–4% for category leaders, 2–3% others.
Retail / E-commerce
- Revenue = same-store sales growth + new store openings (physical) OR GMV growth (digital).
- Working capital matters: inventory turns, payables.
- Split CapEx: maintenance (existing) vs growth (new stores/fulfillment).
- Normalize for one-time charges (store closures, write-downs).
Financial Services (Banks / Insurance)
- Standard DCF is wrong. Use DDM or excess return model.
- If forced: project NII, provisions, non-interest income separately.
- Discount rate = cost of equity only (debt is operational).
Healthcare / Pharma
- Separate existing portfolio from pipeline.
- Key risk: patent cliffs, FDA approval probability.
- R&D: 15–25% of revenue.
- Biotech: risk-adjust pipeline NPV by phase success probability.
Energy (Oil & Gas)
- Revenue tied to commodity prices — use strip pricing or scenarios.
- High CapEx; distinguish development vs exploration.
- Depletion accounting differs from standard D&A.
- Terminal value very sensitive to long-term price deck.
Manufacturing / Industrial
- Cyclical — use mid-cycle earnings for normalization.
- CapEx 8–15% of revenue.
- Working capital swings with cycle — use through-cycle averages.
- WACC 8–11% typical.
Consumer Goods (CPG)
- Stable, predictable — good DCF candidates.
- Distinguish organic vs M&A growth.
- Watch gross margin trends, A&P spend, input costs.
- Terminal growth 2–3% (population + inflation).
Telecommunications
- High CapEx (15–25%) for network buildout.
- Recurring revenue, low churn — good for DCF.
- Spectrum costs lumpy.
- WACC 7–9% for large incumbents.
Real Estate / REITs
- Use NAV as primary; DCF supplementary.
- Project NOI instead of FCF.
- Cap rate replaces WACC at property level.
- Distinguish maintenance vs growth CapEx.
Media / Streaming
- Subscriber growth × ARPU drives revenue.
- Content spend dominant cost — capitalize vs expense debate matters.
- Path to profitability > current margin for growth-stage.
- High operating leverage at scale.
Common Pitfalls
- Terminal value dominance: If TV > 80% of EV, model is really a multiple-expansion bet. Disclose.
- Growth > WACC: Breaks Gordon formula. Cap
gbelow WACC. - Inconsistent tax rates: Historical effective rate may include one-offs. Cross-check with statutory.
- Double-counting SBC: Either subtract SBC from FCFF OR use diluted shares that price it in — not both, and not neither.
- Stale beta: yfinance beta may be 5-year or 3-year. For recent IPOs or post-restructuring businesses, compute fresh.
- Ignoring minority interest / preferred: These are claims on EV ahead of common equity. Always subtract.
- Circular WACC: WACC uses market cap → which is what we're trying to estimate. For IPOs or controversial names, iterate or use target capital structure.
Relative Valuation — Detailed Reference
Relative valuation implies a price by applying peer multiples. Fast, market-anchored, and captures sentiment — but "garbage in, garbage out" when peers are poorly chosen.
Peer Selection Heuristics
Aim for 4–6 peers. More is noisier, fewer is brittle.
| Criterion | Priority |
|---|---|
| Same GICS industry | Must |
| Similar business model (e.g., SaaS vs perpetual license) | Must |
| Similar growth rate (within ±10 percentage points) | Strong preference |
| Similar margin profile | Preference |
| Similar capital structure | Nice to have |
| Similar geographic exposure | Nice to have |
Avoid: Mega-cap diversified companies as peers for pure-play small/mid-caps (e.g., MSFT is not a good peer for DDOG).
Multiples Cheat Sheet
| Multiple | Best for | Avoid for |
|---|---|---|
| P/E (trailing) | Mature, profitable companies | Unprofitable, cyclical troughs |
| P/E (forward) | Growing, earnings-visible | Early-stage, wide estimate dispersion |
| PEG (P/E ÷ growth) | High-growth profitable | Mature low-growth |
| EV/Revenue | Unprofitable, early SaaS | Mature mixed-margin |
| EV/EBITDA | Mid-to-late stage across capital structures | Financials, REITs |
| EV/EBIT | Capital-intensive (excludes D&A smoothing) | Non-comparable D&A conventions |
| P/B | Banks, insurance | Asset-light businesses |
| P/TBV | Banks | Non-financials |
| P/FFO, P/AFFO | REITs | Anything else |
| EV/Sub, EV/MAU | Streaming, social | Not meaningful elsewhere |
Computing Implied Price
For each multiple, take peer median (not mean — medians are robust to outliers).
# Equity multiples
Implied price (P/E) = peer median P/E × target EPS_TTM
# Enterprise multiples
Implied EV (EV/Rev) = peer median EV/Rev × target Revenue_TTM
Implied EV (EV/EBITDA)= peer median EV/EBITDA × target EBITDA_TTM
Net debt = Total Debt − Cash
Implied equity value = Implied EV − Net debt − Minority interest − Preferred
Implied price = Implied equity value / diluted sharesAdjustments — When NOT to Apply Peer Median Blindly
Adjust ±10–30% based on target vs peer median:
| If target has... | Adjust implied multiple |
|---|---|
| Higher growth rate (>500bps above peer median) | +10% to +30% |
| Lower growth rate | −10% to −30% |
| Higher margin (>300bps above peer median) | +10% to +20% |
| Lower margin | −10% to −20% |
| Better balance sheet / lower leverage | +5% to +10% |
| Higher leverage / covenant risk | −10% to −20% |
| Dominant market position / moat | +10% to +20% |
| Category laggard / market share loss | −10% to −20% |
| Regulatory overhang / activist target | −5% to −15% |
Always state the adjustment and the reason.
Rule of 40 for SaaS
For software/SaaS peers, add Rule of 40 as a supplementary anchor:
Rule of 40 = Revenue Growth % + FCF Margin %| Rule of 40 score | Peer EV/Revenue premium |
|---|---|
| ≥ 50 | Top quartile — use 75th percentile peer multiple |
| 40–50 | Above median — use median + 10% |
| 30–40 | Below median — use median − 10% |
| < 30 | Bottom quartile — use 25th percentile peer multiple |
Common Peer Sets (Fallback)
Hardcoded starter sets when industry classification is ambiguous. Expand as needed.
| Theme | Peers |
|---|---|
| Enterprise software (large-cap) | MSFT, ORCL, CRM, NOW, SAP, WDAY |
| Horizontal SaaS mid-cap | DDOG, MDB, NET, SNOW, TEAM, ZS |
| Cybersecurity | CRWD, PANW, ZS, S, NET, FTNT |
| Semiconductors (compute / GPU) | NVDA, AMD, AVGO, INTC, QCOM |
| Semiconductor equipment | AMAT, LRCX, KLAC, ASML |
| Mega-cap internet | GOOGL, META, AMZN, MSFT, AAPL |
| E-commerce | AMZN, SHOP, MELI, SE, ETSY |
| Payments | V, MA, PYPL, AXP, SQ |
| US mega-bank | JPM, BAC, C, WFC, GS, MS |
| Regional banks | PNC, TFC, USB, KEY |
| Life insurance | MET, PRU, LNC, AFL |
| P&C insurance | TRV, CB, ALL, PGR |
| Consumer staples | KO, PEP, PG, CL, UL, MDLZ |
| Tobacco | MO, PM, BTI |
| Fast food | MCD, CMG, YUM, QSR, SBUX |
| Apparel / luxury | LVMUY, NKE, LULU, RL |
| Auto (legacy) | F, GM, STLA, TM, HMC |
| Auto (EV) | TSLA, LCID, RIVN, NIO, XPEV |
| Airlines (US) | DAL, UAL, AAL, LUV, ALK |
| Oil & gas majors | XOM, CVX, SHEL, BP, TTE |
| E&P pure-plays | COP, EOG, PXD, DVN, OXY |
| Pharma (large-cap) | PFE, JNJ, MRK, LLY, ABBV, BMY |
| Biotech large-cap | AMGN, GILD, REGN, VRTX |
| Medical devices | MDT, ABT, BSX, SYK, ISRG |
| Industrial conglomerates | GE, HON, MMM, ITW, EMR |
| Defense | LMT, RTX, NOC, GD, BA |
| Telecom | T, VZ, TMUS, CMCSA |
| Utilities | NEE, DUK, SO, D, AEP |
| REITs (diversified) | PLD, AMT, EQIX, CCI, SPG |
| Streaming | NFLX, DIS, WBD, PARA |
Cross-Check: Target vs Peers Table
Always produce a table of peers with:
- Ticker / name
- Market cap
- Revenue growth (LTM, forward)
- Gross margin, EBITDA margin, operating margin
- P/E (fwd), EV/Revenue, EV/EBITDA
- Peer median (bottom row)
This lets the user see at a glance whether the target "deserves" a premium/discount.
Common Pitfalls
- Using a single multiple: Triangulate with ≥2 multiples. EV/EBITDA should agree with EV/Revenue within ±15% when applied to same peer set.
- Outlier peers: Exclude if P/E > 100 or EV/Rev > 50 unless target is similarly extreme.
- Peer in trough: If peer is in distress or restructuring, their multiple compresses — excluding them or adjusting.
- Different fiscal year ends: Normalize to TTM.
- Stock-based comp: EV/EBITDA without SBC adjustment overstates multiples for SaaS. Consider EV/EBITDA (ex-SBC) for SaaS peers.
- Currency: International peers — normalize to USD and note FX sensitivity.
Sum-of-the-Parts (SOTP) Valuation
For companies with 2+ reporting segments, SOTP values each segment using pure-play peer multiples, sums them, and compares to market cap to detect conglomerate discount.
When to Use SOTP
Triggers:
- Company has 2+ reportable operating segments in 10-K / 20-F
- Segments operate in materially different industries (e.g., tech + retail, media + theme parks)
- One segment appears to grow faster or be more valuable than blended multiple suggests
- SOTP analysis suggests >20% upside vs current market cap (meaningful conglomerate discount)
- Plausible catalyst within 12-24 months: activist, strategic review, rumored spin-off, board pressure
Do not force SOTP when:
- Segments share heavy operational integration (e.g., vertically integrated manufacturers) — synergies would be destroyed by separation
- Segment disclosures are too coarse to model independently
- No realistic path to value realization (management opposed, no activists)
Workflow
Step 1: Extract Segment Financials
From latest 10-K / 10-Q segment disclosure, pull per segment:
- Revenue
- Operating income (EBIT)
- EBITDA (if disclosed, else EBIT + allocated D&A)
- Revenue growth YoY
- Operating margin
Track inter-segment eliminations and unallocated corporate expenses separately.
Step 2: Identify Pure-Play Peers
For each segment, find 3-5 listed pure-play peers in the same industry. Examples:
| Segment type | Pure-play peers |
|---|---|
| Cloud infrastructure | MSFT (Azure), AMZN (AWS), GOOGL (GCP) — for growth multiples |
| Digital advertising | META, GOOGL, TTD, PINS |
| Streaming | NFLX, DIS (DTC), WBD (DTC) |
| Theme parks | SIX, FUN, CCL-adjacent leisure |
| Retail (physical) | WMT, TGT, COST, HD |
| Semiconductors (design) | NVDA, AMD, AVGO, MRVL |
| Semiconductor fab | TSM, INTC (IFS), GFS |
| Auto (legacy) | F, GM, STLA |
| Auto (EV) | TSLA, RIVN, LCID |
| Insurance (P&C) | TRV, CB, ALL, PGR |
| Insurance (life) | MET, PRU, LNC |
| Utility (regulated) | DUK, SO, AEP |
| Pharma / biotech | PFE, MRK, LLY, ABBV |
Record peer median EV/EBITDA, EV/Revenue (for growth segments), and P/E.
Step 3: Apply Multiples
segment_EV_i = segment_EBITDA_i × peer_median_EV/EBITDA_iUse EV/EBITDA as default. For high-growth or pre-profit segments, use EV/Revenue.
Step 4: Adjust for Corporate-Level Items
Total EV from segments
− Unallocated corporate costs (cap at 2-5% of revenue, or discount at 8x the ongoing cost)
− Minority interest
− Total debt
− Preferred stock
− Pension underfunding
+ Cash & equivalents
+ Non-operating assets (excess real estate, investments, NOLs)
= Equity Value
Implied price = Equity Value / diluted sharesStep 5: Compute Conglomerate Discount
discount_pct = (SOTP_price − market_price) / SOTP_price × 100Thresholds:
>30%: compelling; likely actionable20-30%: meaningful; need catalyst10-20%: narrow; requires catalyst + technicals<10%: no opportunity
Step 6: Identify Catalyst
Conglomerate discount can persist indefinitely without a catalyst. Require at least one of:
- Activist investor filed 13D pushing for breakup
- Management publicly discussed "strategic alternatives" or "portfolio simplification"
- Rumored or announced spin-off / divestiture
- CEO change (new CEOs often simplify)
- Peer transaction highlighting valuation gap
- Board refresh with activist nominees
Example
DiverseTech Corp (DVTK) — two segments:
- Cloud Platform: $3B rev, 30% growth, 25% EBITDA margin → $0.75B EBITDA
- Legacy Hardware: $5B rev, flat, 15% EBITDA margin → $0.75B EBITDA
Peer multiples:
- Cloud peers median EV/EBITDA: 20x → cloud EV = $15B
- Hardware peers median EV/EBITDA: 8x → hardware EV = $6B
Total segment EV = $21B
− Corporate costs = $2B
− Net debt = $2B
= Equity value = $17B
Shares out = 250M
Implied SOTP price = $68
Market price = $42
Discount = 38% — compellingCatalyst: Activist filed 13D demanding cloud spin-off. Enter position at $42.
Edge Cases & Traps
| Issue | Handling |
|---|---|
| Shared costs allocated inconsistently | Read 10-K segment footnote; recalculate if allocation is arbitrary |
| Synergy destruction | Deduct 5-15% of segment EV for operational coupling (shared sales, shared R&D) |
| Tax leakage on spin-off / divestiture | Factor 10-20% of realized value as tax cost |
| Minority interest in a segment | Multiply segment EV by parent's ownership % |
| Hidden liabilities (env, pension, litigation) | Review 10-K footnotes; subtract estimated NPV |
| Persistent discount with no catalyst | Don't invest — "dead money" until catalyst materializes |
| Peer group too narrow | Use broader set to avoid anchoring on inflated comps |
| Segment EBITDA before stock comp | Reconcile — SaaS peers may be post-SBC, industrial peers pre-SBC |
Position Sizing (if SOTP feeds into a trade)
- 4-6% of portfolio per SOTP position (value trades with identified catalyst)
- Stop-loss: −15% from entry (wider stop because discount can widen before closing)
- Time stop: 12 months with no catalyst progress → reassess
- Portfolio cap: 15% of capital in SOTP / conglomerate-discount trades (correlated risk)
- Trim when discount narrows to <10%; add when it widens to >35% with no thesis break
Performance Expectations
- Win rate with catalyst: 55-65%
- Win rate without catalyst: 40-45%
- Average winner: +20% to +40% over 12-24 months
- Average loser: −10% to −15%
- Risk/reward with catalyst: 2:1 to 3:1
WACC, ERP, Risk-Free Rates & Sector Benchmarks
Reference values for cost-of-capital inputs. Prefer live values over these defaults when available.
Risk-Free Rate
Use the 10-year sovereign yield of the company's reporting currency.
| Market | Instrument | yfinance ticker | Typical range |
|---|---|---|---|
| US | 10Y Treasury | ^TNX (note: quoted in %, divide by 100) | 3.5-5.0% |
| UK | 10Y Gilt | ^TNX does not cover; use FRED or manual | 3.0-4.5% |
| Germany | 10Y Bund | Manual (ECB) | 2.0-3.5% |
| Japan | 10Y JGB | Manual (BoJ) | 0.5-1.5% |
Live fetch:
import yfinance as yf
rf = yf.Ticker("^TNX").fast_info.last_price / 100Default (when fetch fails): rf = 0.045 (4.5%). Flag as stale.
Equity Risk Premium (ERP)
Use Damodaran's monthly ERP update (damodaran.nyu.edu) as anchor. Intra-year, 5.5% is a reasonable mid-range.
| Market | ERP (default) | Source |
|---|---|---|
| US | 5.5% | Damodaran implied ERP (S&P 500) |
| Developed Europe | 6.0-6.5% | Country risk + base ERP |
| Japan | 6.0% | Country risk + base ERP |
| China | 7.5-8.5% | Base + country risk premium |
| India | 7.5% | Base + country risk premium |
| Emerging (broad) | 8.0-10.0% | Base + country risk |
Adjust with country risk premium (CRP) for emerging markets:
ERP_country = ERP_mature + CRPCost of Debt
Preferred: interest_expense / total_debt from financial statements.
Fallback: credit rating spreads over risk-free rate.
| Rating | Spread over RF | Kd range (at RF=4.5%) |
|---|---|---|
| AAA | 0.5-0.8% | 5.0-5.3% |
| AA | 0.8-1.2% | 5.3-5.7% |
| A | 1.2-1.8% | 5.7-6.3% |
| BBB | 1.8-2.5% | 6.3-7.0% |
| BB | 3.5-5.0% | 8.0-9.5% |
| B | 5.5-7.5% | 10.0-12.0% |
| CCC+ | 9.0%+ | 13.5%+ |
Default (when unknown): kd = 0.055 for large-caps, 0.07 for mid-caps.
Levered Beta Defaults (by sector)
Use when yfinance returns None or an implausible value (e.g., beta < 0 for a non-gold stock).
| Sector | Default beta |
|---|---|
| Utilities | 0.55 |
| Consumer staples | 0.70 |
| Telecom | 0.85 |
| Healthcare / pharma | 0.90 |
| REITs | 0.90 |
| Industrials | 1.05 |
| Financials (banks) | 1.15 |
| Consumer discretionary | 1.20 |
| Energy (integrated) | 1.10 |
| Energy (E&P) | 1.40 |
| Technology (large-cap) | 1.15 |
| Technology (SaaS high-growth) | 1.35 |
| Semiconductors | 1.45 |
| Biotech (clinical stage) | 1.60 |
| Auto (EV pure-play) | 1.80 |
Source: Damodaran industry betas (levered, US-listed, recent year-end update).
WACC Sanity Ranges by Sector
If computed WACC falls outside these bands, double-check inputs (beta, capital structure, kd).
| Sector | WACC range | Notes |
|---|---|---|
| Utilities | 5-7% | High debt capacity, low beta |
| Consumer staples | 7-9% | Low beta, moderate leverage |
| Telecom (large) | 7-9% | Heavy debt, moderate beta |
| Healthcare / pharma | 8-10% | Moderate beta, moderate leverage |
| REITs | 6-8% | High debt (but use WACD + cost of equity separately) |
| Industrials | 8-11% | Cyclical, moderate leverage |
| Financials | 9-12% | High beta, but debt is operational (use cost of equity only) |
| Consumer discretionary | 9-11% | Cyclical, higher beta |
| Energy (majors) | 8-10% | Moderate beta, strong BS |
| Energy (E&P) | 10-12% | High beta, commodity exposure |
| Technology (large-cap) | 8-11% | Low debt, moderate beta |
| SaaS high-growth | 10-13% | High beta, minimal debt → cost of equity dominates |
| Semiconductors | 10-12% | High beta, cyclical |
| Biotech | 11-14% | Very high beta, often pre-revenue |
Size Premium (CRSP / Ibbotson style)
Small / micro caps justify additional return above CAPM. Add to ke if applicable.
| Market cap | Size premium |
|---|---|
| > $20B (mega) | 0% |
| $10-20B (large) | 0% |
| $2-10B (mid) | 0.5-1.0% |
| $500M-$2B (small) | 1.5-2.5% |
| $100-500M (micro) | 2.5-4.0% |
| < $100M (nano) | 4.0%+ |
Terminal Growth Rate Ceilings
Terminal g must be plausible relative to long-run nominal GDP growth. Hard ceilings:
| Economy | Long-run nominal GDP | Max defensible g |
|---|---|---|
| US | 4.0-4.5% | 3.0% |
| Developed Europe | 3.0-4.0% | 2.5% |
| Japan | 1.5-2.5% | 1.5% |
| China | 5.0-6.0% | 4.0% |
| India | 7.0-9.0% | 5.0% |
Global-franchise exporters can argue slightly above local GDP, but rarely above +0.5%.
Cross-Check: Implied Cost of Equity
Back-solve from current multiples to sanity-check WACC:
Forward earnings yield ≈ 1 / forward P/E
Implied ke ≈ earnings yield + sustainable growthIf computed WACC diverges from this implied number by >300bps, one of the inputs (beta, ERP, growth) is off.
Related skills
How it compares
Use company-valuation when you need multi-method triangulation with sensitivity tables rather than a single quick multiple lookup.
FAQ
What valuation methods does company-valuation combine?
company-valuation combines a 5-year DCF, relative valuation using peer median P/E, EV/Revenue, and EV/EBITDA across 4–6 peers, and sum-of-parts when 2 or more segments exist. Results blend into one implied share price with explicit method weights and sensitivity tables.
Where does company-valuation pull financial data from?
company-valuation pulls 5 years of financial statements and analyst estimates through yfinance before building DCF assumptions, peer multiples, and optional SOTP segment valuations for the target public ticker.
Is Company Valuation safe to install?
skills.sh reports 2 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.