English · 简体中文
DCF Quick
A reusable skill that has a coding agent run a simplified two-stage DCF, and that forces the
production of a downside floor and a position ceiling derived from the worst case.
Same philosophy as Zara Zhang's frontend-slides — reusable, reproducible, verifiable — and
complementary to valuation-comps: this skill supplies the absolute anchor, comps the relative one,
and the two cross-check each other.
This skill runs scripts/dcf_calc.py for all arithmetic. The agent fetches data and sets
assumptions; the script handles discounting, sensitivity, the downside floor and position sizing, so
you don't stack mental-math errors on top of "garbage in, garbage out".
Core discipline (before any calculation)
Work out how much you can lose before thinking about how much you might make. The position
conclusion is not built on the base case — it's built on the downside floor: recompute
intrinsic value under worst-case assumptions, compare against the current price to get the margin of
safety, and only if the floor still leaves enough buffer can you talk about whether to buy and how
much. This matches Leo's hard rule — position size is derived from the worst case, not from the size
of the opportunity.
When to use
- You need an absolute valuation anchor (comps only tell you relative cheapness; DCF tells you what
it's worth).
- You want a quick read on whether the margin of safety is sufficient.
- You want to convert "how much should I buy" from a guess into something derived from the worst case.
The eight steps (leave a trace at each)
- Define target and vantage: ticker / name plus a buy-side vantage. Record current price, shares
outstanding, market cap and net debt (net debt = interest-bearing debt − cash).
- Take the FCF base: preferably operating cash flow − capex (from
westock-data or the filings).
If FCF isn't disclosed, approximate with net income + D&A − capex and label it "approximate".
- Set the two stages: explicit period N = 5–10 years, with staged or year-by-year growth rates
(justified by history, industry, consensus). Terminal value uses Gordon (g below long-run GDP /
inflation) or an exit EV/EBITDA multiple — pick one and say why (see
references/dcf_methodology.md).
- Set WACC: discount rate = risk-free + risk premium + beta / size premium. WACC is not a tuning
knob; assumptions must be defensible (see the defensible ranges and red lines in
references/assumptions_bounds.md).
- Compute present value: the script discounts explicit-period FCF plus discounted terminal value
to enterprise value; subtract net debt for equity value, divide by shares for intrinsic value per
share (base case).
- Sensitivity: a WACC × growth (or terminal multiple) matrix giving a range of intrinsic value per
share, not a point.
- Downside derivation (mandatory): compress assumptions to worst case (growth cut 30–50%, WACC
raised 100–150bp, margin compression) and recompute the downside floor per share. Compare
against price for the margin of safety.
- Conclude plus position ceiling: based on the floor, give a maximum position (rules in the
script and
references/assumptions_bounds.md): floor above 1.5× price → consider building a
position; 1.0–1.5× → small position only; below 1.0× → don't touch. Name the variables that would
trigger a re-run.
Data sources (in priority order; never fabricate)
westock-data first: market cap, net debt, FCF, consensus estimates.
- Fallbacks:
akshare-stock / neodata-financial-search for A-share detail.
- Last resort:
WebSearch / WebFetch — annual reports, IR, quote pages.
- Mark any missing field
N/A with source and reason. Never fill placeholder numbers.
Output format (one page of Markdown; structure in examples/sample-dcf.md)
- Assumptions table (FCF base, N, growth, WACC, terminal method);
- Discounting table (explicit period + terminal value);
- Sensitivity matrix;
- Downside floor block (worst-case assumptions + result + margin of safety);
- Position ceiling conclusion (from the worst case, not the opportunity size);
- Append the raw
scripts/dcf_calc.py output so it's reproducible.
Checks and red lines (reliability floor)
- WACC ≤ terminal growth g → the script throws an error (Gordon diverges); do not compute anyway.
- Base-case per share deviating from the comps-implied value by more than 20% → you may not state
both "buy" and "cheap"; resolve the conflict first.
- The downside floor must be below the base case (worst case cannot exceed the optimistic case) —
otherwise the assumptions contradict each other.
- Stamp every assumption with data date and source; WACC or growth outside the defensible band in
references/assumptions_bounds.md must be explicitly argued.
Boundaries and disclaimer
- A DCF is extremely sensitive to assumptions — garbage in, garbage out. Always cross-check with
valuation-comps.
- The downside floor is a discipline tool, not a precise bottom. It answers "can I live with the worst
case", not "how high will it go".
- Stamp data date and source. Investment decisions belong to a human; this skill produces a
reproducible analysis skeleton.
Layout
dcf-quick/
SKILL.md # this file (English)
SKILL_CN.md # 简体中文版
README.md
references/
dcf_methodology.md # two-stage model, terminal method choice, discounting detail
assumptions_bounds.md # defensible ranges and red lines for WACC / growth / margin
scripts/
dcf_calc.py # calculation core (base / sensitivity / downside floor / position)
dcf_calc_test.py # unit tests
examples/
sample-dcf.md # anonymised sample
1---2name: dcf-quick3title: DCF Quick — One-Page DCF, Position Sized from the Downside4summary: Give it a ticker and it produces a one-page two-stage DCF range plus a downside floor, then derives the maximum position from the worst case rather than from the size of the opportunity. A quantitative exoskeleton for investing discipline.5read_when:6 - user wants absolute valuation / a DCF, but wants it fast, reproducible and readable on one page7 - user asks what a company is intrinsically worth and whether the margin of safety is enough8 - user wants the worst case settled before deciding position size (sizing from the downside)9 - user mentions "dcf" "discounted cash flow" "intrinsic value" "margin of safety" "position sizing"10---111213> **English** · [简体中文](SKILL_CN.md)1415# DCF Quick1617A reusable skill that has a coding agent run a **simplified two-stage DCF**, and that forces the18production of a **downside floor** and a **position ceiling derived from the worst case**.19Same philosophy as Zara Zhang's `frontend-slides` — reusable, reproducible, verifiable — and20complementary to `valuation-comps`: this skill supplies the absolute anchor, comps the relative one,21and the two cross-check each other.2223**This skill runs `scripts/dcf_calc.py` for all arithmetic.** The agent fetches data and sets24assumptions; the script handles discounting, sensitivity, the downside floor and position sizing, so25you don't stack mental-math errors on top of "garbage in, garbage out".2627## Core discipline (before any calculation)28**Work out how much you can lose before thinking about how much you might make.** The position29conclusion is **not built on the base case** — it's built on the **downside floor**: recompute30intrinsic value under worst-case assumptions, compare against the current price to get the margin of31safety, and only if the floor still leaves enough buffer can you talk about whether to buy and how32much. This matches Leo's hard rule — position size is derived from the worst case, not from the size33of the opportunity.3435## When to use36- You need an absolute valuation anchor (comps only tell you relative cheapness; DCF tells you what37 it's worth).38- You want a quick read on whether the margin of safety is sufficient.39- You want to convert "how much should I buy" from a guess into something derived from the worst case.4041## The eight steps (leave a trace at each)42431. **Define target and vantage**: ticker / name plus a buy-side vantage. Record current price, shares44 outstanding, market cap and net debt (net debt = interest-bearing debt − cash).452. **Take the FCF base**: preferably operating cash flow − capex (from `westock-data` or the filings).46 If FCF isn't disclosed, approximate with net income + D&A − capex and label it "approximate".473. **Set the two stages**: explicit period N = 5–10 years, with staged or year-by-year growth rates48 (justified by history, industry, consensus). Terminal value uses Gordon (g below long-run GDP /49 inflation) **or** an exit EV/EBITDA multiple — pick one and say why (see50 `references/dcf_methodology.md`).514. **Set WACC**: discount rate = risk-free + risk premium + beta / size premium. WACC is not a tuning52 knob; assumptions must be defensible (see the defensible ranges and red lines in53 `references/assumptions_bounds.md`).545. **Compute present value**: the script discounts explicit-period FCF plus discounted terminal value55 to enterprise value; subtract net debt for equity value, divide by shares for intrinsic value per56 share (base case).576. **Sensitivity**: a WACC × growth (or terminal multiple) matrix giving a range of intrinsic value per58 share, not a point.597. **Downside derivation (mandatory)**: compress assumptions to worst case (growth cut 30–50%, WACC60 raised 100–150bp, margin compression) and recompute the **downside floor** per share. Compare61 against price for the margin of safety.628. **Conclude plus position ceiling**: based on the floor, give a **maximum position** (rules in the63 script and `references/assumptions_bounds.md`): floor above 1.5× price → consider building a64 position; 1.0–1.5× → small position only; below 1.0× → don't touch. Name the variables that would65 trigger a re-run.6667## Data sources (in priority order; never fabricate)68- `westock-data` first: market cap, net debt, FCF, consensus estimates.69- Fallbacks: `akshare-stock` / `neodata-financial-search` for A-share detail.70- Last resort: `WebSearch` / `WebFetch` — annual reports, IR, quote pages.71- Mark any missing field `N/A` with source and reason. Never fill placeholder numbers.7273## Output format (one page of Markdown; structure in `examples/sample-dcf.md`)74- Assumptions table (FCF base, N, growth, WACC, terminal method);75- Discounting table (explicit period + terminal value);76- Sensitivity matrix;77- **Downside floor** block (worst-case assumptions + result + margin of safety);78- Position ceiling conclusion (from the worst case, not the opportunity size);79- Append the raw `scripts/dcf_calc.py` output so it's reproducible.8081## Checks and red lines (reliability floor)82- WACC ≤ terminal growth g → the script throws an error (Gordon diverges); do not compute anyway.83- Base-case per share deviating from the comps-implied value by more than 20% → you may not state84 both "buy" and "cheap"; resolve the conflict first.85- The downside floor must be below the base case (worst case cannot exceed the optimistic case) —86 otherwise the assumptions contradict each other.87- Stamp every assumption with data date and source; WACC or growth outside the defensible band in88 `references/assumptions_bounds.md` must be explicitly argued.8990## Boundaries and disclaimer91- A DCF is extremely sensitive to assumptions — garbage in, garbage out. Always cross-check with92 `valuation-comps`.93- The downside floor is a discipline tool, not a precise bottom. It answers "can I live with the worst94 case", not "how high will it go".95- Stamp data date and source. Investment decisions belong to a human; this skill produces a96 reproducible analysis skeleton.9798## Layout99```100dcf-quick/101 SKILL.md # this file (English)102 SKILL_CN.md # 简体中文版103 README.md104 references/105 dcf_methodology.md # two-stage model, terminal method choice, discounting detail106 assumptions_bounds.md # defensible ranges and red lines for WACC / growth / margin107 scripts/108 dcf_calc.py # calculation core (base / sensitivity / downside floor / position)109 dcf_calc_test.py # unit tests110 examples/111 sample-dcf.md # anonymised sample112```