Company Valuation

by himself6501fc7b4b34aeNo license3.3K starsListed Oct 8, 2026Updated Oct 8, 2026Repository updated 3 days ago

Estimate a public company's intrinsic value with DCF, relative (peer multiple), and sum-of-the-parts (SOTP) methods, then blend them into an implied share price with upside/downside vs the market price, a WACC and terminal-growth sensitivity grid, and bull/base/bear scenarios. Use this skill whenever the user asks what a company or ticker is worth: fair value, intrinsic value, implied share price, a price target from fundamentals, whether it is overvalued or undervalued, building a DCF (WACC, terminal value, discounted cash flow), EV/EBITDA or P/E based targets, peer comparison valuation, or SOTP and conglomerate discounts. Run the model rather than answering valuation questions from memory.

AI-generated overview

Estimates a public company's intrinsic value using DCF, peer multiples and sum-of-the-parts, blended into an implied share price.

What it does
This skill builds a three-method valuation of a public company: a five-year discounted cash flow model, a relative valuation against peer multiples, and a sum-of-the-parts valuation when multiple reporting segments exist. It blends the method outputs into an implied share price with upside or downside versus the market price, and adds a WACC by terminal-growth sensitivity grid plus bull, base and bear scenarios. It produces a structured written valuation report with assumption tables, peer comparison, sensitivity matrix and key risks, and states that the output is research or educational and not financial advice.
When to use it
Use it when a user asks what a company or ticker is worth, including fair value, intrinsic value, implied share price, a fundamentals-based price target, or whether a stock looks overvalued or undervalued. It also fits requests to build a DCF, derive EV/EBITDA or P/E based targets, compare against peers, or run a sum-of-the-parts analysis.
Requirements
Requires Python 3 with yfinance, numpy and pandas; the skill can pip-install yfinance if missing. It needs network access to fetch market data and a live 10-year Treasury yield, falling back to a default risk-free rate if that fetch fails. Segment data for sum-of-the-parts must be supplied by the user or parsed from filings, since yfinance does not expose it. No scripts ship with the skill; it is instructions only.

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 2 method paths — pick the richest one available.

Environment status:

!`python3 -c "exec('try:\n import yfinance, numpy, pandas\n print(\'YFIN_OK\')\nexcept Exception:\n print(\'YFIN_MISSING\')')"`
!`python3 -c "exec('try:\n import yfinance as yf\n t=yf.Ticker(\'^TNX\')\n p=t.fast_info.last_price\n print(f\'RF_10Y={p/100:.4f}\')\nexcept Exception:\n print(\'RF_FETCH_FAIL\')')"`

Decision tree:

ConditionMethod path
YFIN_OKPath A (primary): yfinance for financials + peer multiples
YFIN_MISSINGPath B: pip-install yfinance, then Path A. python3 -m pip install -q yfinance numpy pandas
RF_FETCH_FAILUse 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 typeDCFRelativeSOTPFallback
Mature cash-flow (CPG, telecom, utilities)✅ primary✅❌—
High-growth SaaS / software✅ with care✅ primary❌Use EV/Revenue + Rule of 40
Multi-segment conglomerate✅✅✅ primarySee 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✅sometimesNormalize through-cycle

Defaults table

Settle every parameter before pulling data — these defaults apply unless the user overrides them.

ParameterDefaultRationale
Projection horizon5 yearsStandard explicit forecast window
Terminal growth g2.5%~ long-run US GDP
Risk-free rate rfLive 10Y UST from Step 1, else 4.5%Current cost of capital anchor
Equity risk premium erp5.5%Damodaran mid-range
Betainfo['beta'] from yfinanceMarket-observed levered beta
Cost of debt kdinterest_expense / total_debt, else 5.5%Effective rate; fallback to IG spread
Tax rate3-yr median effective rate, floored 15%, capped 30%Strips out one-offs
Margin assumptions3-yr median of each ratioSmooths cyclical noise
SBC treatmentCash for software/SaaS; non-cash for industrials/CPGIndustry convention
Peer count4-6Balances signal vs noise
Peer multipleMedian (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 gridWACC ±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

python
import yfinance as yfimport numpy as npimport pandas as pd
TICKER = "AAPL"  # replacet = yf.Ticker(TICKER)
info       = t.infoincome_a   = t.income_stmtcashflow_a = t.cashflowbalance_a  = t.balance_sheetincome_q   = t.quarterly_income_stmtcashflow_q = t.quarterly_cashflow
earnings_est = t.earnings_estimaterevenue_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 0cash        = info.get("totalCash") or 0beta        = info.get("beta") or 1.0sector      = info.get("sector")industry    = info.get("industry")

Key financial statement rows (yfinance labels):

NeedRow
RevenueTotal Revenue
EBITOperating Income
Net incomeNet Income
D&ADepreciation And Amortization (in cashflow)
CapExCapital Expenditure (negative)
ΔNWCChange In Working Capital (cashflow)
SBCStock Based Compensation (cashflow)

Step 4: DCF Build

Full methodology + industry-specific tweaks in references/dcf.md. Quick skeleton:

python
# 4a. Revenue growth path — fade from Y1 (consensus or hist CAGR) to terminal grev = income_a.loc["Total Revenue"].dropna().iloc[::-1].values  # yfinance columns are newest-first; reverse to oldest -> newesthist_cagr = (rev[-1] / rev[0]) ** (1 / (len(rev)-1)) - 1y1 = float(revenue_est.loc["+1y", "growth"]) if "+1y" in revenue_est.index else hist_cagrg_terminal = 0.025growth_path = np.linspace(y1, g_terminal + 0.01, 5)
# 4b. Margins — 3y medianebit_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())eff_tax     = (income_a.loc["Tax Provision"] / income_a.loc["Pretax Income"]).iloc[:3].median()tax_rate    = float(min(0.30, max(0.15, eff_tax))) if pd.notna(eff_tax) else 0.21  # 3y median effective, floored 15%, capped 30%
# 4c. FCFF per yearrev_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. WACCrf, erp, kd = 0.045, 0.055, 0.055  # override rf with live value from Step 1ke = rf + beta * erpe_v = market_cap / (market_cap + total_debt)d_v = 1 - e_vwacc = e_v*ke + d_v*kd*(1 - tax_rate)
# 4e. Terminal value — compute both, use midpointtv_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/EBITDAtv_base   = 0.5 * (tv_gordon + tv_exit)
# 4f. Bridge to equitypv_fcff = sum(f / (1+wacc)**(i+1) for i, f in enumerate(fcff))pv_tv   = tv_base / (1+wacc)**5ev      = pv_fcff + pv_tvequity  = ev + cash - total_debtimplied_price_dcf = equity / shares_out

Gates: (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.

python
PEERS = ["MSFT", "ORCL", "CRM", "NOW", "SAP", "WDAY"]  # pick by industrymultiples = {}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_ttmimplied_ev_rev   = (med_ev_rev * rev_ttm - net_debt) / shares_outimplied_ev_ebit  = (med_ev_eb  * ebitda_ttm - net_debt) / shares_outimplied_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

python
# Blended implied priceif sotp_price is None:    blended = 0.5*implied_price_dcf + 0.5*implied_price_relelse:    blended = 0.4*implied_price_dcf + 0.3*implied_price_rel + 0.3*sotp_price
# 5x5 sensitivity gridwacc_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_out

Also 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

Present the valuation in this order:

  1. Headline verdict — one sentence with the blended fair value, the current price, the % upside or downside, and which method is most bullish or bearish.
  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 — which assumptions move the answer most, and what could break the thesis.

Error handling

Missing / edge caseAction
yfinance returns None for betaUse sector-default beta from references/wacc_erp_rates.md
Negative LTM EBITDASkip EV/EBITDA multiple; rely on EV/Revenue + DCF
Negative LTM EPSSkip P/E multiple; use forward P/E if positive, else skip
Growth > WACC in GordonCap g = wacc − 0.5% and flag
Fewer than 3 years historyUse what's available; flag data confidence as "low"
Peer data fetch failsDrop that peer from median; note in output
No segment data for SOTPSkip 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 theme
  • references/sotp.md — Sum-of-parts methodology, conglomerate discount detection, catalysts
  • references/wacc_erp_rates.md — Risk-free rates, equity risk premiums, sector WACC benchmarks, sector-default betas

Source and attribution

Source:himself65/finance-skillsinplugins/market-analysis/skills/company-valuationat commit01fc7b4

License: No license

Content belongs to its original authors. SourceWeft indexes it from a public repository.

Report or request removal

More from himself65/finance-skills

Yfinance Data

himself65

Fetches stock and market data from Yahoo Finance via the yfinance Python library and presents it.

Data & Analytics3.3Kupdated 3 days ago

Stock Liquidity

himself65

Analyze how liquid a stock is using Yahoo Finance data (yfinance): bid-ask spreads, volume and dollar volume (ADTV), top-of-book and options depth, square-root market impact and slippage estimates, turnover ratio, and Amihud illiquidity, rolled into a liquidity grade. Use this skill whenever the user asks about liquidity or trading costs — how easily a position can be entered or exited, what a large order would do to the price, spread or execution-cost estimates, order book depth, volume patterns, or liquidity comparisons — especially for small caps, penny stocks, and thinly traded names.

Awaiting classification3.3Kupdated 3 days ago

Stock Correlation

himself65

Analyzes stock co-movement from Yahoo Finance price history, finding correlated peers, betas, clusters and rolling correlations.

Data & Analytics3.3Kupdated 3 days ago

Sepa Strategy

himself65

Analyzes stocks using Mark Minervini's SEPA methodology: stage analysis, trend template, patterns, entries and position sizing.

Business & Finance3.3Kupdated 3 days ago

Saas Valuation Compression

himself65

Analyzes how a private SaaS company's ARR valuation multiple changed across funding rounds and attributes the change to macro, growth and narrative factors.

Business & Finance3.3Kupdated 3 days ago

Yc Reader

himself65

Look up Y Combinator companies and batches from the public yc-oss API, a static JSON dataset refreshed daily: company profiles, batch rosters (e.g. W25, S24), companies by industry or tag, top companies, who is hiring, founder-diversity lists, and overall YC stats. Use this skill whenever the user asks about YC-backed startups, a YC batch, YC companies in a sector or tag or that are hiring, the Y Combinator portfolio, or startup and venture research that draws on YC data. Read-only.

Awaiting classification3.3Kupdated 3 days ago