원클릭으로
dcf-model
// DCF valuation: free cash flow projections, WACC, terminal value, sensitivity analysis
// DCF valuation: free cash flow projections, WACC, terminal value, sensitivity analysis
| name | dcf-model |
| description | DCF valuation: free cash flow projections, WACC, terminal value, sensitivity analysis |
| license | Derived from anthropics/financial-services-plugins (Apache-2.0). Modified for langalpha. |
This skill creates institutional-quality DCF models for equity valuation following investment banking standards. Each analysis produces a detailed Excel model (with sensitivity analysis included at the bottom of the DCF sheet).
get_financial_statements, get_financial_ratios, get_growth_metrics, get_historical_valuationget_treasury_rates, get_market_risk_premiumget_company_overview tool: analyst consensus, growth estimates, company profileThese constraints apply throughout all DCF model building. Review before starting:
Sensitivity Tables:
Cell Comments:
Model Layout Planning:
Formula Recalculation:
python skills/xlsx/scripts/recalc.py model.xlsx 30 before deliveryScenario Blocks:
=IF($B$6=1,[Bear cell],IF($B$6=2,[Base cell],[Bull cell]))Execution pattern: build the DCF as a saved Python script (e.g., work/<task_name>/build_dcf.py) rather than inline ExecuteCode. Model building is iterative — you will debug formulas, tweak assumptions, and rerun. Writing to a file + running via Bash lets you Edit specific sections and rerun cheaply; resubmitting the whole openpyxl block inline on every iteration is wasteful.
Fetch data from MCP servers, user provided data, and the web.
Data Sources:
get_financial_statements(symbol, 'all', 'annual', 5)get_financial_ratios(symbol)get_growth_metrics(symbol)get_treasury_rates() -- use the 10Y rateget_market_risk_premium()get_company_overview tool -- includes analyst consensus and growth estimatesget_historical_valuation(symbol)Validation Checklist:
Analyze and document:
Create summary tables showing:
Historical Metrics (LTM):
Revenue: $X million
Revenue growth: X% CAGR
Gross margin: X%
EBIT margin: X%
D&A % of revenue: X%
CapEx % of revenue: X%
FCF margin: X%
Methodology:
Growth Rate Framework:
Formula structure:
Three-scenario approach:
Bear Case: Conservative growth (e.g., 8-12%)
Base Case: Most likely scenario (e.g., 12-16%)
Bull Case: Optimistic growth (e.g., 16-20%)
Fixed/Variable Cost Analysis:
Operating expenses should model realistic operating leverage:
Key principles:
Margin expansion framework:
Current State → Target State (Year 5)
Gross Margin: X% → Y% (justify based on scale, efficiency)
EBIT Margin: X% → Y% (result of revenue growth + opex leverage)
Build FCF in proper sequence:
EBIT
(-) Taxes (EBIT × Tax Rate)
= NOPAT (Net Operating Profit After Tax)
(+) D&A (non-cash expense, % of revenue)
(-) CapEx (% of revenue, typically 4-8%)
(-) Δ NWC (change in working capital)
= Unlevered Free Cash Flow
Working Capital Modeling:
Maintenance vs Growth CapEx:
CAPM Methodology for Cost of Equity:
Cost of Equity = Risk-Free Rate + Beta × Equity Risk Premium
Where:
- Risk-Free Rate = Current 10-Year Treasury Yield (use macro MCP: `get_treasury_rates()`)
- Beta = 5-year monthly stock beta vs market index
- Equity Risk Premium = use macro MCP: `get_market_risk_premium()` (typically 5.0-6.0%)
Cost of Debt Calculation:
After-Tax Cost of Debt = Pre-Tax Cost of Debt × (1 - Tax Rate)
Determine Pre-Tax Cost of Debt from:
- Credit rating (if available)
- Current yield on company bonds
- Interest expense / Total Debt from financials
Capital Structure Weights:
Market Value Equity = Current Stock Price × Shares Outstanding
Net Debt = Total Debt - Cash & Equivalents
Enterprise Value = Market Cap + Net Debt
Equity Weight = Market Cap / Enterprise Value
Debt Weight = Net Debt / Enterprise Value
WACC = (Cost of Equity × Equity Weight) + (After-Tax Cost of Debt × Debt Weight)
Special Cases:
Typical WACC Ranges:
Mid-Year Convention:
Present Value Calculation:
For each projection year:
PV of FCF = Unlevered FCF × Discount Factor
Example (Year 1):
FCF = $1,000
WACC = 10%
Period = 0.5
Discount Factor = 1 / (1.10)^0.5 = 0.9535
PV = $1,000 × 0.9535 = $954
Projection Period Selection:
Perpetuity Growth Method (Preferred):
Terminal FCF = Final Year FCF × (1 + Terminal Growth Rate)
Terminal Value = Terminal FCF / (WACC - Terminal Growth Rate)
Critical Constraint: Terminal Growth < WACC (otherwise infinite value)
Terminal Growth Rate Selection:
Do not exceed: Risk-free rate or long-term GDP growth
Exit Multiple Method (Alternative):
Terminal Value = Final Year EBITDA × Exit Multiple
Where Exit Multiple comes from:
- Industry comparable trading multiples
- Precedent transaction multiples
- Typical range: 8-15x EBITDA
Present Value of Terminal Value:
PV of Terminal Value = Terminal Value / (1 + WACC)^Final Period
Where Final Period accounts for timing:
5-year model with mid-year convention: Period = 4.5
Terminal Value Sanity Check:
Valuation Summary Structure:
(+) Sum of PV of Projected FCFs = $X million
(+) PV of Terminal Value = $Y million
= Enterprise Value = $Z million
(-) Net Debt [or + Net Cash if negative] = $A million
= Equity Value = $B million
÷ Diluted Shares Outstanding = C million shares
= Implied Price per Share = $XX.XX
Current Stock Price = $YY.YY
Implied Return = (Implied Price / Current Price) - 1 = XX%
Critical Adjustments:
Valuation Output Format:
Valuation Component,Amount ($M)
PV Explicit FCFs,X.X
PV Terminal Value,Y.Y
Enterprise Value,Z.Z
(-) Net Debt,A.A
Equity Value,B.B
,,
Shares Outstanding (M),C.C
Implied Price per Share,$XX.XX
Current Share Price,$YY.YY
Implied Upside/(Downside),+XX%
Build three sensitivity tables at the bottom of the DCF sheet showing how valuation changes with different assumptions:
Implementation: These are simple 2D grids (NOT Excel's "Data Table" feature) with formulas in each cell. Each cell must contain a full DCF recalculation for that specific assumption combination. See Critical Constraints section for detailed requirements on populating all 75 cells programmatically using openpyxl.
<correct_patterns>
This section contains all the CORRECT patterns to follow when building DCF models.
Assumptions are organized in separate blocks for each scenario:
CRITICAL STRUCTURE - Three rows per section header:
BEAR CASE ASSUMPTIONS (section header, merge cells across)
Assumption,FY1,FY2,FY3,FY4,FY5
Revenue Growth (%),12%,10%,9%,8%,7%
EBIT Margin (%),45%,44%,43%,42%,41%
BASE CASE ASSUMPTIONS (section header, merge cells across)
Assumption,FY1,FY2,FY3,FY4,FY5
Revenue Growth (%),16%,14%,12%,10%,9%
EBIT Margin (%),48%,49%,50%,51%,52%
BULL CASE ASSUMPTIONS (section header, merge cells across)
Assumption,FY1,FY2,FY3,FY4,FY5
Revenue Growth (%),20%,18%,15%,13%,11%
EBIT Margin (%),50%,51%,52%,53%,54%
Each scenario block MUST have a column header row showing the projection years (FY2025E, FY2026E, etc.) immediately below the section title. Without this, users cannot tell which assumption value corresponds to which year.
How to reference assumptions - Create a consolidation column:
Recommended consolidation column pattern (using INDEX):
=INDEX(B10:D10, 1, $B$6)
NOT this - scattered IF statements throughout:
=IF($B$6=1,[Bear block cell],IF($B$6=2,[Base block cell],[Bull block cell]))
The consolidation column approach centralizes logic and makes the model easier to audit.
Create a consolidation column with INDEX formulas, then reference it in projections:
Step 1 - Consolidation column for FY1 growth:
=INDEX([Bear FY1 growth]:[Bull FY1 growth], 1, $B$6)
Step 2 - Revenue projection references the consolidation column:
Revenue Year 1: =D29*(1+$E$10)
Where:
This approach is cleaner than embedding IF statements in every projection formula and makes it much easier to audit which scenario assumptions are being used.
Use consolidation columns with INDEX formulas, then reference them in FCF calculations:
Consolidation column approach:
Item,Formula,Reference
D&A,=E29*$E$21,$E$21 = consolidation column for D&A %
CapEx,=E29*$E$22,$E$22 = consolidation column for CapEx %
Δ NWC,=(E29-D29)*$E$23,$E$23 = consolidation column for NWC %
Unlevered FCF,=E57+E58-E60-E62,E57=NOPAT E58=D&A E60=CapEx E62=Δ NWC
Each consolidation column cell contains an INDEX formula that pulls from the appropriate scenario block based on case selector. This keeps projection formulas clean and auditable.
Before writing formulas, confirm scenario block row locations and set up consolidation columns.
Every hardcoded value needs this format:
"Source: [System/Document], [Date], [Reference], [URL if applicable]"
Examples:
Item,Source Comment
Stock price,Source: get_company_overview 2025-10-12 Close price
Shares outstanding,Source: fundamentals MCP get_financial_statements FY2024
Historical revenue,Source: fundamentals MCP get_financial_statements FY2024
Beta,Source: get_company_overview 2025-10-12 5-year monthly beta
Risk-free rate,Source: macro MCP get_treasury_rates 2025-10-12 10Y yield
Consensus estimates,Source: get_company_overview analyst consensus
CRITICAL: Each scenario block requires THREE structural elements:
Structure:
BEAR CASE ASSUMPTIONS (section header - merge across columns A:G)
Assumption,FY1,FY2,FY3,FY4,FY5
Revenue Growth (%),X%,X%,X%,X%,X%
EBIT Margin (%),X%,X%,X%,X%,X%
Terminal Growth,X%,,,,
WACC,X%,,,,
BASE CASE ASSUMPTIONS (section header - merge across columns A:G)
Assumption,FY1,FY2,FY3,FY4,FY5
Revenue Growth (%),X%,X%,X%,X%,X%
EBIT Margin (%),X%,X%,X%,X%,X%
Terminal Growth,X%,,,,
WACC,X%,,,,
BULL CASE ASSUMPTIONS (section header - merge across columns A:G)
Assumption,FY1,FY2,FY3,FY4,FY5
Revenue Growth (%),X%,X%,X%,X%,X%
EBIT Margin (%),X%,X%,X%,X%,X%
Terminal Growth,X%,,,,
WACC,X%,,,,
WITHOUT the column header row showing projection years (FY2025E, FY2026E, etc.), users cannot tell which assumption value corresponds to which year. This row is MANDATORY.
Then create a consolidation column (typically the next column to the right) that uses INDEX formulas to pull from the selected scenario block based on the case selector. This consolidation column is what your projection formulas reference.
1. Write ALL headers and labels FIRST:
Row,Content
1,[Company Name] DCF Model
2,Ticker | Date | Year End
4,Case Selector
7,KEY ASSUMPTIONS
26,Assumption headers
27-31,Growth assumptions
...,...
2. Write ALL section dividers and blank rows
3. THEN write formulas using the locked row positions
4. Test formulas immediately after creation
Think of it like construction:
Excel version:
IMPORTANT: These are NOT Excel's "Data Table" feature. These are simple grids where you write regular formulas using openpyxl. Yes, this means ~75 formulas total (3 tables × 25 cells each), but this is straightforward and required.
Programmatic Population with Formulas:
Each sensitivity table must be fully populated with formulas that recalculate the implied share price for each combination of assumptions. Do not use Excel's Data Table feature (it requires manual intervention and cannot be automated via openpyxl).
Implementation approach - CONCRETE EXAMPLE:
Table Structure (5x5 grid):
WACC vs Terminal Growth,2.0%,2.5%,3.0%,3.5%,4.0%
8.0%,[B88 formula],[C88 formula],[D88 formula],[E88 formula],[F88 formula]
9.0%,[B89 formula],[C89 formula],[D89 formula],[E89 formula],[F89 formula]
...,...,...,...,...,...
Formula Pattern - Cell B88 (WACC=8.0%, Terminal Growth=2.0%):
The formula in B88 should recalculate the implied price using:
$A88 (8.0%)B$87 (2.0%)Recommended approach: Reference the main DCF calculation but substitute these values.
Example formula structure:
=([SUM of PV FCFs using $A88 as discount rate] + [Terminal Value using B$87 as growth rate and $A88 as WACC] - [Net Debt]) / [Shares]
CRITICAL - Write a formula for EVERY cell in the 5x5 grid (25 cells per table, 75 cells total). Use openpyxl to write these formulas programmatically in a loop. Do NOT skip this step or leave placeholder text.
Python implementation pattern:
# Pseudocode for populating sensitivity table
for row_idx, wacc_value in enumerate(wacc_range):
for col_idx, term_growth_value in enumerate(term_growth_range):
# Build formula that uses wacc_value and term_growth_value
formula = f"=<DCF recalc using {wacc_value} and {term_growth_value}>"
ws.cell(row=start_row+row_idx, column=start_col+col_idx).value = formula
The sensitivity tables must work immediately when the model is opened, with no manual steps required from the user.
</correct_patterns>
<common_mistakes>
This section contains all the WRONG patterns to avoid when building DCF models.
Don't use linear approximations:
// WRONG - Linear approximation
B97: =B88*(1+(0.096-0.116)) // Assumes linear relationship
// WRONG - Division shortcut
B105: =B88/(1+(E48-0.07)) // Doesn't recalculate full DCF
Don't leave placeholder text:
// WRONG - Placeholder note
"Note: Use Excel Data Table feature (Data → What-If Analysis → Data Table) to populate sensitivity tables."
// WRONG - Empty cells
[leaving cells blank because "this is complex"]
Don't confuse terminology:
Why these shortcuts are wrong:
Common rationalization to REJECT: "Writing 75+ formulas feels complex, so I'll leave a note for the user to complete it manually."
Reality: Writing 75 formulas is straightforward when you use a loop in Python with openpyxl. Each formula follows the same pattern - just substitute the row/column values. This is a required part of the deliverable.
Instead: Populate every sensitivity cell with formulas that recalculate the full DCF for that specific combination of assumptions
Don't do this:
Why it's wrong:
Instead: Add cell comment AS EACH hardcoded value is created
Symptom:
The FCF section references wrong assumption rows:
D&A: =E29*$E$34 // Should be $E$21, but referencing wrong row
CapEx: =E29*$E$41 // Should be $E$22, but row shifted
Why this happens:
Instead: Lock row layout FIRST, then write formulas
Don't structure assumptions like this:
Assumption,Bear,Base,Bull
Revenue Growth FY1,10%,13%,16%
Revenue Growth FY2,9%,12%,15%
This vertical layout makes it hard to see the progression across years within each scenario.
Why it's wrong:
Instead:
Don't deliver a model without borders:
Why it's wrong:
Instead: Add borders around all major sections
Don't do this:
Why it's wrong:
Instead: Blue text for ALL hardcoded inputs, black text for ALL formulas, green for sheet links
Don't do this:
S&M: =E33*0.15 // E33 = Gross Profit (WRONG)
Why it's wrong:
Instead:
S&M: =E29*0.15 // E29 = Revenue (CORRECT)
In addition, be aware of these errors:
These errors are the most common. Re-read this section before starting any DCF build.
</common_mistakes>
For all Excel formatting, number formats, and color standards, follow the guidelines in skills/xlsx/SKILL.md.
After generating Excel, run recalculation: python skills/xlsx/scripts/recalc.py model.xlsx 30
Every DCF model must maximize for:
Create two sheets:
CRITICAL: Sensitivity tables go at the BOTTOM of the DCF sheet (not on a separate sheet). This keeps all valuation outputs together.
After creating or modifying the Excel model, run recalculation:
python skills/xlsx/scripts/recalc.py [path_to_excel_file] [timeout_seconds]
Example:
python skills/xlsx/scripts/recalc.py $WORK_DIR/work/{task}/AAPL_DCF_Model.xlsx 30
Fix all errors and re-run until status is "success" before delivering the model. See skills/xlsx/SKILL.md for output format and error handling details.
For all Excel formatting, number formats, and color standards, follow the guidelines in skills/xlsx/SKILL.md.
After generating Excel, run recalculation: python skills/xlsx/scripts/recalc.py model.xlsx 30
Section 1: Header
Row,Content
1,[Company Name] DCF Model
2,Ticker: [XXX] | Date: [Date] | Year End: [FYE]
3,Blank
4,Case Selector Cell (1=Bear 2=Base 3=Bull)
5,Case Name Display (formula: =IF([Selector]=1"Bear"IF([Selector]=2"Base""Bull")))
Section 2: Market Data (NOT case dependent)
Item,Value
Current Stock Price,$XX.XX
Shares Outstanding (M),XX.X
Market Cap ($M),[Formula]
Net Debt ($M),XXX [or Net Cash if negative]
Section 3: DCF Scenario Assumptions
Create separate assumption blocks for each scenario (Bear, Base, Bull) with DCF-specific assumptions (Revenue Growth %, EBIT Margin %, Tax Rate %, D&A % of Revenue, CapEx % of Revenue, NWC Change % of ΔRev, Terminal Growth Rate, WACC) laid out horizontally across projection years. Each block must include section header, column header row showing the projection years (FY1, FY2, etc.), and data rows. See <correct_patterns> section "Correct Assumption Table Structure" for the exact layout.
Section 4: Historical & Projected Financials
Reference a consolidation column (e.g., "Selected Case") that pulls from scenario blocks, not scattered IF formulas in every projection row.
Income Statement ($M),2020A,2021A,2022A,2023A,2024E,2025E,2026E
Revenue,XXX,XXX,XXX,XXX,[=E29*(1+$E$10)],[=F29*(1+$E$11)],[=G29*(1+$E$12)]
% growth,XX%,XX%,XX%,XX%,[=E29/D29-1],[=F29/E29-1],[=G29/F29-1]
,,,,,,
Gross Profit,XXX,XXX,XXX,XXX,[=E29*E33],[=F29*F33],[=G29*G33]
% margin,XX%,XX%,XX%,XX%,[=E33/E29],[=F33/F29],[=G33/G29]
,,,,,,
Operating Expenses:,,,,,,,
S&M,XXX,XXX,XXX,XXX,[=E29*0.15],[=F29*0.14],[=G29*0.13]
R&D,XXX,XXX,XXX,XXX,[=E29*0.12],[=F29*0.11],[=G29*0.10]
G&A,XXX,XXX,XXX,XXX,[=E29*0.08],[=F29*0.07],[=G29*0.07]
Total OpEx,XXX,XXX,XXX,XXX,[=E36+E37+E38],[=F36+F37+F38],[=G36+G37+G38]
,,,,,,
EBIT,XXX,XXX,XXX,XXX,[=E33-E39],[=F33-F39],[=G33-G39]
% margin,XX%,XX%,XX%,XX%,[=E41/E29],[=F41/F29],[=G41/G29]
,,,,,,
Taxes,(XX),(XX),(XX),(XX),[=E41*$E$24],[=F41*$E$24],[=G41*$E$24]
Tax rate,XX%,XX%,XX%,XX%,[=E43/E41],[=F43/F41],[=G43/G41]
,,,,,,
NOPAT,XXX,XXX,XXX,XXX,[=E41-E43],[=F41-F43],[=G41-G43]
Key Formula Pattern:
=E29*(1+$E$10) where $E$10 is consolidation column for Year 1 growth=E29*(1+IF($B$6=1,$B$10,IF($B$6=2,$C$10,$D$10)))This approach is cleaner, easier to audit, and prevents formula errors by centralizing the scenario logic.
Section 5: Free Cash Flow Build
CRITICAL: Verify row references point to the CORRECT assumption rows. Test formulas immediately after creation.
Cash Flow ($M),2020A,2021A,2022A,2023A,2024E,2025E,2026E
NOPAT,XXX,XXX,XXX,XXX,[=E45],[=F45],[=G45]
(+) D&A,XXX,XXX,XXX,XXX,[=E29*$E$21],[=F29*$E$21],[=G29*$E$21]
% of Rev,XX%,XX%,XX%,XX%,[=E58/E29],[=F58/F29],[=G58/G29]
(-) CapEx,(XX),(XX),(XX),(XX),[=E29*$E$22],[=F29*$E$22],[=G29*$E$22]
% of Rev,XX%,XX%,XX%,XX%,[=E60/E29],[=F60/F29],[=G60/G29]
(-) Δ NWC,(XX),(XX),(XX),(XX),[=(E29-D29)*$E$23],[=(F29-E29)*$E$23],[=(G29-F29)*$E$23]
% of Δ Rev,XX%,XX%,XX%,XX%,[=E62/(E29-D29)],[=F62/(F29-E29)],[=G62/(G29-F29)]
,,,,,,
Unlevered FCF,XXX,XXX,XXX,XXX,[=E57+E58-E60-E62],[=F57+F58-F60-F62],[=G57+G58-G60-G62]
Row reference examples (based on layout planning):
Before writing formulas: Confirm these row numbers match the actual layout. Test one column, then copy across.
Section 6: Discounting & Valuation
DCF Valuation,2024E,2025E,2026E,2027E,2028E,Terminal
Unlevered FCF ($M),XXX,XXX,XXX,XXX,XXX,
Period,0.5,1.5,2.5,3.5,4.5,
Discount Factor,0.XX,0.XX,0.XX,0.XX,0.XX,
PV of FCF ($M),XXX,XXX,XXX,XXX,XXX,
,,,,,,
Terminal FCF ($M),,,,,,,XXX
Terminal Value ($M),,,,,,,XXX
PV Terminal Value ($M),,,,,,,XXX
,,,,,,
Valuation Summary ($M),,,,,,
Sum of PV FCFs,XXX,,,,,
PV Terminal Value,XXX,,,,,
Enterprise Value,XXX,,,,,
(-) Net Debt,(XX),,,,,
Equity Value,XXX,,,,,
,,,,,,
Shares Outstanding (M),XX.X,,,,,
IMPLIED PRICE PER SHARE,$XX.XX,,,,,
Current Stock Price,$XX.XX,,,,,
Implied Upside/(Downside),XX%,,,,,
COST OF EQUITY CALCULATION,,
Risk-Free Rate (10Y Treasury),X.XX%,[macro MCP: get_treasury_rates()]
Beta (5Y monthly),X.XX,[Input]
Equity Risk Premium,X.XX%,[macro MCP: get_market_risk_premium()]
Cost of Equity,X.XX%,[Calculated blue]
,,
COST OF DEBT CALCULATION,,
Credit Rating,AA-,[Yellow input]
Pre-Tax Cost of Debt,X.XX%,[Yellow input]
Tax Rate,XX.X%,[Link to DCF sheet]
After-Tax Cost of Debt,X.XX%,[Calculated blue]
,,
CAPITAL STRUCTURE,,
Current Stock Price,$XX.XX,[Link to DCF]
Shares Outstanding (M),XX.X,[Link to DCF]
Market Capitalization ($M),"X,XXX",[Calculated]
,,
Total Debt ($M),XXX,[Yellow input]
Cash & Equivalents ($M),XXX,[Yellow input]
Net Debt ($M),XXX,[Calculated]
,,
Enterprise Value ($M),"X,XXX",[Calculated]
,,
WACC CALCULATION,Weight,Cost,Contribution
Equity,XX.X%,X.X%,X.XX%
Debt,XX.X%,X.X%,X.XX%
,,
WEIGHTED AVERAGE COST OF CAPITAL,X.XX%,[Green output]
Key WACC Formulas:
Market Cap = Price × Shares
Net Debt = Total Debt - Cash
Enterprise Value = Market Cap + Net Debt
Equity Weight = Market Cap / EV
Debt Weight = Net Debt / EV
WACC = (Cost of Equity × Equity Weight) + (After-tax Cost of Debt × Debt Weight)
TERMINOLOGY REMINDER: "Sensitivity tables" = simple 2D grids with row headers, column headers, and formulas in each data cell. NOT Excel's "Data Table" feature (Data → What-If Analysis → Data Table). You will use openpyxl to write regular Excel formulas into each cell.
Location: Rows 87+ on DCF sheet (NOT a separate sheet)
Three sensitivity tables, vertically stacked:
Total formulas to write: 75 (this is required, not optional)
CRITICAL: All sensitivity table cells must be populated programmatically with formulas using openpyxl. DO NOT use linear approximation shortcuts. DO NOT leave placeholder text or notes about manual steps. DO NOT rationalize leaving cells empty because "it's complex" - use a Python loop to generate the formulas.
Table Setup:
No manual intervention required - the sensitivity tables must be fully functional when the user opens the file.
Three-Case Framework:
Formula Implementation:
DO NOT use nested IF formulas scattered throughout. Instead, create a consolidation column that uses INDEX or OFFSET formulas to pull from the appropriate scenario block.
Recommended pattern (using INDEX):
=INDEX(B10:D10, 1, $B$6) where B10:D10 = Bear/Base/Bull values, 1 = row offset, $B$6 = case selector cell (1, 2, or 3)
Then reference the consolidation column in all projections:
Revenue Year 1: =D29*(1+$E$10) where $E$10 is the consolidation column value for Year 1 growth.
This approach centralizes scenario logic, making the model easier to audit and maintain.
File naming: [Ticker]_DCF_Model_[Date].xlsx
Two sheets:
Key features: Case selector (1/2/3), consolidation column with INDEX/OFFSET formulas, color-coded cells, cell comments on all inputs, professional borders
If you encounter errors or unreasonable results, read TROUBLESHOOTING.md for detailed debugging guidance.
Gather market data:
get_company_overview tool for stock price, beta, shares outstanding, analyst consensusget_treasury_rates() for risk-free rate (10Y)get_market_risk_premium() for equity risk premiumGather historical financials:
get_financial_statements(symbol, 'all', 'annual', 5) for income/balance/cash flowget_financial_ratios(symbol) for ratiosget_growth_metrics(symbol) for growth ratesBegin model construction using the DCF methodology detailed in this skill
Verify structure:
Recalculate formulas: Run python skills/xlsx/scripts/recalc.py model.xlsx 30
Check output:
status is "success" → Continue to step 4status is "errors_found" → Check error_summary and read TROUBLESHOOTING.md for debugging guidanceFix errors and re-run recalc.py until status is "success"
Spot-check formulas:
Deliver model
get_financial_statements, get_financial_ratios, get_growth_metrics, get_historical_valuationget_treasury_rates, get_market_risk_premiumget_company_overview tool: stock price, beta, shares, analyst consensus, growth estimatesBefore delivering DCF model:
Required:
python skills/xlsx/scripts/recalc.py model.xlsx 30 until status is "success" (zero formula errors)Validation:
[Ticker]_DCF_Model_[Date].xlsxManage user profile including watchlists, portfolio, and preferences.
Inline HTML widgets: charts, dashboards, data tables rendered directly in the chat via ShowWidget
Web scraping with Scrapling: MCP tool wrappers for quick fetching, plus direct Python API for advanced scraping with selectors, sessions, and spiders
Use this skill any time a spreadsheet file is the primary input or output. This means any task where the user wants to: open, read, edit, or fix an existing .xlsx, .xlsm, .csv, or .tsv file (e.g., adding columns, computing formulas, formatting, charting, cleaning messy data); create a new spreadsheet from scratch or from other data sources; or convert between tabular file formats. Trigger especially when the user references a spreadsheet file by name or path — even casually (like "the xlsx in my downloads") — and wants something done to it or produced from it. Also trigger for cleaning or restructuring messy tabular data files (malformed rows, misplaced headers, junk data) into proper spreadsheets. The deliverable must be a spreadsheet file. Do NOT trigger when the primary deliverable is a Word document, HTML report, standalone Python script, database pipeline, or Google Sheets API integration, even if tabular data is involved.
Search X (Twitter) posts, pull user profiles, fetch specific tweets, and read reply threads for sentiment, news, and event research. Triggers on 'X', 'Twitter', 'tweets about', 'sentiment on', 'what are people saying about', 'historical tweets', or any request to read public X content.
Report issues and propose fixes to improve your own capabilities when you encounter errors or limitations