{"kind":"Skill","metadata":{"namespace":"community","name":"dcf-model","version":"0.1.0"},"spec":{"description":"Real DCF (Discounted Cash Flow) model creation for equity valuation. Retrieves financial data from SEC filings and analyst reports, builds comprehensive cash flow projections with proper WACC calculations, performs sensitivity analysis, and outputs professional Excel models with executive summaries. Use when users need to value a company using DCF methodology, request intrinsic value analysis, or ask for detailed financial modeling with growth projections and terminal value calculations.","files":{"SKILL.md":"---\nname: dcf-model\ndescription: Real DCF (Discounted Cash Flow) model creation for equity valuation. Retrieves financial data from SEC filings and analyst reports, builds comprehensive cash flow projections with proper WACC calculations, performs sensitivity analysis, and outputs professional Excel models with executive summaries. Use when users need to value a company using DCF methodology, request intrinsic value analysis, or ask for detailed financial modeling with growth projections and terminal value calculations.\n---\n\n# DCF Model Builder\n\n## Overview\n\nThis 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).\n\n## Tools\n\n- Default to using all of the information provided by the user and MCP servers available for data sourcing.\n\n## Critical Constraints - Read These First\n\nThese constraints apply throughout all DCF model building. Review before starting:\n\n**Environment: Office JS vs Python/openpyxl:**\n- **If running inside Excel (Office Add-in / Office JS environment):** Use Office JS directly — do NOT use Python/openpyxl. Write formulas via `range.formulas = [[\"=D19*(1+$B$8)\"]]`. No separate recalc step needed; Excel calculates natively. Use `range.format.*` for styling. The same formulas-over-hardcodes rule applies: set `.formulas`, never `.values` for derived cells.\n- **If generating a standalone .xlsx file (no live Excel session):** Use Python/openpyxl as described below, then run `recalc.py` before delivery.\n- The rest of this skill uses openpyxl examples — translate to Office JS API calls when in that environment, but all principles (formula strings, cell comments, section checkpoints, sensitivity table loops) apply identically.\n\n**⚠️ Office JS merged cell pitfall:** When building section headers with merged cells, do NOT call `.merge()` then set `.values` on the merged range — Office JS still reports the range's original dimensions and will throw `InvalidArgument: The number of rows or columns in the input array doesn't match the size or dimensions of the range`. Instead, write the value to the top-left cell alone, then merge and format the full range:\n\n```js\n// WRONG — throws InvalidArgument:\nconst hdr = ws.getRange(\"A7:H7\");\nhdr.merge();\nhdr.values = [[\"MARKET DATA \u0026 KEY INPUTS\"]];  // 1×1 array vs 1×8 range → fails\n\n// CORRECT — value first on single cell, then merge + format the range:\nws.getRange(\"A7\").values = [[\"MARKET DATA \u0026 KEY INPUTS\"]];\nconst hdr = ws.getRange(\"A7:H7\");\nhdr.merge();\nhdr.format.fill.color = \"#1F4E79\";\nhdr.format.font.bold = true;\nhdr.format.font.color = \"#FFFFFF\";\n```\n\nThis applies to every merged section header in the DCF (market data, scenario blocks, cash flow projection, terminal value, valuation summary, sensitivity tables).\n\n**Formulas Over Hardcodes (NON-NEGOTIABLE):**\n- Every projection, margin, discount factor, PV, and sensitivity cell MUST be a live Excel formula — never a value computed in Python and written as a number\n- When using openpyxl: `ws[\"D20\"] = \"=D19*(1+$B$8)\"` is correct; `ws[\"D20\"] = calculated_revenue` is WRONG\n- The only hardcoded numbers permitted are: (1) raw historical inputs, (2) assumption drivers (growth rates, WACC inputs, terminal g), (3) current market data (share price, debt balance)\n- If you catch yourself computing something in Python and writing the result — STOP. The model must flex when the user changes an assumption.\n\n**Verify Step-by-Step With the User (DO NOT build end-to-end):**\n- After data retrieval → show the user the raw inputs block (revenue, margins, shares, net debt) and confirm before projecting\n- After revenue projections → show the projected top line and growth rates, confirm before building margin build\n- After FCF build → show the full FCF schedule, confirm logic before computing WACC\n- After WACC → show the calculation and inputs, confirm before discounting\n- After terminal value + PV → show the equity bridge (EV → equity value → per share), confirm before sensitivity tables\n- Catch errors at each stage — a wrong margin assumption discovered after sensitivity tables are built means rebuilding everything downstream\n\n**Sensitivity Tables:**\n- **Use an ODD number of rows and columns** (standard: 5×5, sometimes 7×7) — this guarantees a true center cell\n- **Center cell = base case.** Build the axis values so the middle row header and middle column header exactly equal the model's actual assumptions (e.g., if base WACC = 9.0%, the middle row is 9.0%; if terminal g = 3.0%, the middle column is 3.0%). The center cell's output must therefore equal the model's actual implied share price — this is the sanity check that the table is built correctly.\n- **Highlight the center cell** with the medium-blue fill (`#BDD7EE`) + bold font so it's immediately visible which cell is the base case.\n- Populate ALL cells (typically 3 tables × 25 cells = 75) with full DCF recalculation formulas\n- Use openpyxl loops (or Office JS loops) to write formulas programmatically\n- NO placeholder text, NO linear approximations, NO manual steps required\n- Each cell must recalculate full DCF for that assumption combination\n\n**Cell Comments:**\n- Add cell comments AS each hardcoded value is created\n- Format: \"Source: [System/Document], [Date], [Reference], [URL if applicable]\"\n- Every blue input must have a comment before moving to next section\n- Do not defer to end or write \"TODO: add source\"\n\n**Model Layout Planning:**\n- Define ALL section row positions BEFORE writing any formulas\n- Write ALL headers and labels first\n- Write ALL section dividers and blank rows second\n- THEN write formulas using the locked row positions\n- Test formulas immediately after creation\n\n**Formula Recalculation:**\n- Run `python recalc.py model.xlsx 30` before delivery\n- Fix ALL errors until status is \"success\"\n- Zero formula errors required (#REF!, #DIV/0!, #VALUE!, etc.)\n\n**Scenario Blocks:**\n- Create separate blocks for Bear/Base/Bull cases\n- Show assumptions horizontally across projection years within each block\n- Use IF formulas: `=IF($B$6=1,[Bear cell],IF($B$6=2,[Base cell],[Bull cell]))`\n- Verify formulas reference correct scenario block cells\n\n## DCF Process Workflow\n\n### Step 1: Data Retrieval and Validation\n\nFetch data from MCP servers, user provided data, and the web.\n\n**Data Sources Priority:**\n1. **MCP Servers** (if configured) - Structured financial data from providers like Daloopa\n2. **User-Provided Data** - Historical financials from their research\n3. **Web Search/Fetch** - Current prices, beta, debt and cash when needed\n\n**Validation Checklist:**\n- Verify net debt vs net cash (critical for valuation)\n- Confirm diluted shares outstanding (check for recent buybacks/issuances)\n- Validate historical margins are consistent with business model\n- Cross-check revenue growth rates with industry benchmarks\n- Verify tax rate is reasonable (typically 21-28%)\n\n### Step 2: Historical Analysis (3-5 years)\n\nAnalyze and document:\n- **Revenue growth trends**: Calculate CAGR, identify drivers\n- **Margin progression**: Track gross margin, EBIT margin, FCF margin\n- **Capital intensity**: D\u0026A and CapEx as % of revenue\n- **Working capital efficiency**: NWC changes as % of revenue growth\n- **Return metrics**: ROIC, ROE trends\n\nCreate summary tables showing:\n```\nHistorical Metrics (LTM):\nRevenue: $X million\nRevenue growth: X% CAGR\nGross margin: X%\nEBIT margin: X%\nD\u0026A % of revenue: X%\nCapEx % of revenue: X%\nFCF margin: X%\n```\n\n### Step 3: Build Revenue Projections\n\n**Methodology:**\n1. Start with latest actual revenue (LTM or most recent fiscal year)\n2. Apply growth rates for each projection year\n3. Show both dollar amounts AND calculated growth %\n\n**Growth Rate Framework:**\n- Year 1-2: Higher growth reflecting near-term visibility\n- Year 3-4: Gradual moderation toward industry average\n- Year 5+: Approaching terminal growth rate\n\n**Formula structure:**\n- Revenue(Year N) = Revenue(Year N-1) × (1 + Growth Rate)\n- Growth %(Year N) = Revenue(Year N) / Revenue(Year N-1) - 1\n\n**Three-scenario approach:**\n```\nBear Case: Conservative growth (e.g., 8-12%)\nBase Case: Most likely scenario (e.g., 12-16%)\nBull Case: Optimistic growth (e.g., 16-20%)\n```\n\n### Step 4: Operating Expense Modeling\n\n**Fixed/Variable Cost Analysis:**\n\nOperating expenses should model realistic operating leverage:\n- **Sales \u0026 Marketing**: Typically 15-40% of revenue depending on business model\n- **Research \u0026 Development**: Typically 10-30% for technology companies\n- **General \u0026 Administrative**: Typically 8-15% of revenue, shows leverage as company scales\n\n**Key principles:**\n- ALL percentages based on REVENUE, not gross profit\n- Model operating leverage: % should decline as revenue scales\n- Maintain separate line items for S\u0026M, R\u0026D, G\u0026A\n- Calculate EBIT = Gross Profit - Total OpEx\n\n**Margin expansion framework:**\n```\nCurrent State → Target State (Year 5)\nGross Margin: X% → Y% (justify based on scale, efficiency)\nEBIT Margin: X% → Y% (result of revenue growth + opex leverage)\n```\n\n### Step 5: Free Cash Flow Calculation\n\n**Build FCF in proper sequence:**\n\n```\nEBIT\n(-) Taxes (EBIT × Tax Rate)\n= NOPAT (Net Operating Profit After Tax)\n(+) D\u0026A (non-cash expense, % of revenue)\n(-) CapEx (% of revenue, typically 4-8%)\n(-) Δ NWC (change in working capital)\n= Unlevered Free Cash Flow\n```\n\n**Working Capital Modeling:**\n- Calculate as % of revenue change (delta revenue)\n- Typical range: -2% to +2% of revenue change\n- Negative number = source of cash (working capital release)\n- Positive number = use of cash (working capital build)\n\n**Maintenance vs Growth CapEx:**\n- Maintenance CapEx: Sustains current operations (~2-3% revenue)\n- Growth CapEx: Supports expansion (additional 2-5% revenue)\n- Total CapEx should align with company's growth strategy\n\n### Step 6: Cost of Capital (WACC) Research\n\n**CAPM Methodology for Cost of Equity:**\n\n```\nCost of Equity = Risk-Free Rate + Beta × Equity Risk Premium\n\nWhere:\n- Risk-Free Rate = Current 10-Year Treasury Yield\n- Beta = 5-year monthly stock beta vs market index\n- Equity Risk Premium = 5.0-6.0% (market standard)\n```\n\n**Cost of Debt Calculation:**\n\n```\nAfter-Tax Cost of Debt = Pre-Tax Cost of Debt × (1 - Tax Rate)\n\nDetermine Pre-Tax Cost of Debt from:\n- Credit rating (if available)\n- Current yield on company bonds\n- Interest expense / Total Debt from financials\n```\n\n**Capital Structure Weights:**\n\n```\nMarket Value Equity = Current Stock Price × Shares Outstanding\nNet Debt = Total Debt - Cash \u0026 Equivalents\nEnterprise Value = Market Cap + Net Debt\n\nEquity Weight = Market Cap / Enterprise Value\nDebt Weight = Net Debt / Enterprise Value\n\nWACC = (Cost of Equity × Equity Weight) + (After-Tax Cost of Debt × Debt Weight)\n```\n\n**Special Cases:**\n- **Net Cash Position**: If Cash \u003e Debt, Net Debt is NEGATIVE\n  - Debt Weight may be negative\n  - WACC calculation adjusts accordingly\n- **No Debt**: WACC = Cost of Equity\n\n**Typical WACC Ranges:**\n- Large Cap, Stable: 7-9%\n- Growth Companies: 9-12%\n- High Growth/Risk: 12-15%\n\n### Step 7: Discount Rate Application (5-10 Year Forecast)\n\n**Mid-Year Convention:**\n- Cash flows assumed to occur mid-year\n- Discount Period: 0.5, 1.5, 2.5, 3.5, 4.5, etc.\n- Discount Factor = 1 / (1 + WACC)^Period\n\n**Present Value Calculation:**\n```\nFor each projection year:\nPV of FCF = Unlevered FCF × Discount Factor\n\nExample (Year 1):\nFCF = $1,000\nWACC = 10%\nPeriod = 0.5\nDiscount Factor = 1 / (1.10)^0.5 = 0.9535\nPV = $1,000 × 0.9535 = $954\n```\n\n**Projection Period Selection:**\n- **5 years**: Standard for most analyses\n- **7-10 years**: High growth companies with longer runway\n- **3 years**: Mature, stable businesses\n\n### Step 8: Terminal Value Calculation\n\n**Perpetuity Growth Method (Preferred):**\n\n```\nTerminal FCF = Final Year FCF × (1 + Terminal Growth Rate)\nTerminal Value = Terminal FCF / (WACC - Terminal Growth Rate)\n\nCritical Constraint: Terminal Growth \u003c WACC (otherwise infinite value)\n```\n\n**Terminal Growth Rate Selection:**\n- Conservative: 2.0-2.5% (GDP growth rate)\n- Moderate: 2.5-3.5%\n- Aggressive: 3.5-5.0% (only for market leaders)\n\n**Do not exceed**: Risk-free rate or long-term GDP growth\n\n**Exit Multiple Method (Alternative):**\n```\nTerminal Value = Final Year EBITDA × Exit Multiple\n\nWhere Exit Multiple comes from:\n- Industry comparable trading multiples\n- Precedent transaction multiples\n- Typical range: 8-15x EBITDA\n```\n\n**Present Value of Terminal Value:**\n```\nPV of Terminal Value = Terminal Value / (1 + WACC)^Final Period\n\nWhere Final Period accounts for timing:\n5-year model with mid-year convention: Period = 4.5\n```\n\n**Terminal Value Sanity Check:**\n- Should represent 50-70% of Enterprise Value\n- If \u003e75%, model may be over-reliant on terminal assumptions\n- If \u003c40%, check if terminal assumptions are too conservative\n\n### Step 9: Enterprise to Equity Value Bridge\n\n**Valuation Summary Structure:**\n\n```\n(+) Sum of PV of Projected FCFs = $X million\n(+) PV of Terminal Value = $Y million\n= Enterprise Value = $Z million\n\n(-) Net Debt [or + Net Cash if negative] = $A million\n= Equity Value = $B million\n\n÷ Diluted Shares Outstanding = C million shares\n= Implied Price per Share = $XX.XX\n\nCurrent Stock Price = $YY.YY\nImplied Return = (Implied Price / Current Price) - 1 = XX%\n```\n\n**Critical Adjustments:**\n- **Net Debt = Total Debt - Cash \u0026 Equivalents**\n  - If positive: Subtract from EV (reduces equity value)\n  - If negative (Net Cash): Add to EV (increases equity value)\n- **Use Diluted Shares**: Includes options, RSUs, convertible securities\n- **Other adjustments** (if applicable):\n  - Minority interests\n  - Pension liabilities\n  - Operating lease obligations\n\n**Valuation Output Format:**\n```csv\nValuation Component,Amount ($M)\nPV Explicit FCFs,X.X\nPV Terminal Value,Y.Y\nEnterprise Value,Z.Z\n(-) Net Debt,A.A\nEquity Value,B.B\n,,\nShares Outstanding (M),C.C\nImplied Price per Share,$XX.XX\nCurrent Share Price,$YY.YY\nImplied Upside/(Downside),+XX%\n```\n\n### Step 10: Sensitivity Analysis\n\nBuild **three sensitivity tables** at the bottom of the DCF sheet showing how valuation changes with different assumptions:\n\n1. **WACC vs Terminal Growth** - Shows enterprise value sensitivity to discount rate and perpetuity growth\n2. **Revenue Growth vs EBIT Margin** - Shows impact of top-line growth and operating leverage\n3. **Beta vs Risk-Free Rate** - Shows sensitivity to cost of equity components\n\n**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.\n\n\u003ccorrect_patterns\u003e\n\nThis section contains all the CORRECT patterns to follow when building DCF models.\n\n### Scenario Block Selection Pattern - Follow This Approach\n\n**Assumptions are organized in separate blocks for each scenario:**\n\n**CRITICAL STRUCTURE - Three rows per section header:**\n\n```csv\nBEAR CASE ASSUMPTIONS (section header, merge cells across)\nAssumption,FY1,FY2,FY3,FY4,FY5\nRevenue Growth (%),12%,10%,9%,8%,7%\nEBIT Margin (%),45%,44%,43%,42%,41%\n\nBASE CASE ASSUMPTIONS (section header, merge cells across)\nAssumption,FY1,FY2,FY3,FY4,FY5\nRevenue Growth (%),16%,14%,12%,10%,9%\nEBIT Margin (%),48%,49%,50%,51%,52%\n\nBULL CASE ASSUMPTIONS (section header, merge cells across)\nAssumption,FY1,FY2,FY3,FY4,FY5\nRevenue Growth (%),20%,18%,15%,13%,11%\nEBIT Margin (%),50%,51%,52%,53%,54%\n```\n\n**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.\n\n**How to reference assumptions - Create a consolidation column:**\n1. Case selector cell (e.g., B6) contains 1=Bear, 2=Base, or 3=Bull\n2. Create a consolidation column with INDEX or OFFSET formulas to pull from the correct scenario block\n3. Projection formulas reference the consolidation column (clean cell references)\n4. Each scenario block contains full set of DCF assumptions across projection years\n\n**Recommended consolidation column pattern (using INDEX):**\n`=INDEX(B10:D10, 1, $B$6)`\n\n**NOT this - scattered IF statements throughout:**\n`=IF($B$6=1,[Bear block cell],IF($B$6=2,[Base block cell],[Bull block cell]))`\n\nThe consolidation column approach centralizes logic and makes the model easier to audit.\n\n### Correct Revenue Projection Pattern\n\n**Create a consolidation column with INDEX formulas, then reference it in projections:**\n\n**Step 1 - Consolidation column for FY1 growth:**\n`=INDEX([Bear FY1 growth]:[Bull FY1 growth], 1, $B$6)`\n\n**Step 2 - Revenue projection references the consolidation column:**\n`Revenue Year 1: =D29*(1+$E$10)`\n\nWhere:\n- D29 = Prior year revenue\n- $E$10 = Consolidation column cell for FY1 growth (contains INDEX formula)\n- $B$6 = Case selector (1=Bear, 2=Base, 3=Bull)\n\n**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.\n\n### Correct FCF Formula Pattern\n\n**Use consolidation columns with INDEX formulas, then reference them in FCF calculations:**\n\n**Consolidation column approach:**\n```csv\nItem,Formula,Reference\nD\u0026A,=E29*$E$21,$E$21 = consolidation column for D\u0026A %\nCapEx,=E29*$E$22,$E$22 = consolidation column for CapEx %\nΔ NWC,=(E29-D29)*$E$23,$E$23 = consolidation column for NWC %\nUnlevered FCF,=E57+E58-E60-E62,E57=NOPAT E58=D\u0026A E60=CapEx E62=Δ NWC\n```\n\n**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.\n\nBefore writing formulas, confirm scenario block row locations and set up consolidation columns.\n\n### Correct Cell Comment Format\n\n**Every hardcoded value needs this format:**\n\n\"Source: [System/Document], [Date], [Reference], [URL if applicable]\"\n\n**Examples:**\n```csv\nItem,Source Comment\nStock price,Source: Market data script 2025-10-12 Close price\nShares outstanding,Source: 10-K FY2024 Page 45 Note 12\nHistorical revenue,Source: 10-K FY2024 Page 32 Consolidated Statements\nBeta,Source: Market data script 2025-10-12 5-year monthly beta\nConsensus estimates,Source: Management guidance Q3 2024 earnings call\n```\n\n### Correct Assumption Table Structure\n\n**CRITICAL: Each scenario block requires THREE structural elements:**\n\n1. **Section header row** (merged cells): e.g., \"BEAR CASE ASSUMPTIONS\"\n2. **Column header row** showing years - THIS IS REQUIRED, DO NOT SKIP\n3. **Data rows** with assumption values\n\n**Structure:**\n```csv\nBEAR CASE ASSUMPTIONS (section header - merge across columns A:G)\nAssumption,FY1,FY2,FY3,FY4,FY5\nRevenue Growth (%),X%,X%,X%,X%,X%\nEBIT Margin (%),X%,X%,X%,X%,X%\nTerminal Growth,X%,,,,\nWACC,X%,,,,\n\nBASE CASE ASSUMPTIONS (section header - merge across columns A:G)\nAssumption,FY1,FY2,FY3,FY4,FY5\nRevenue Growth (%),X%,X%,X%,X%,X%\nEBIT Margin (%),X%,X%,X%,X%,X%\nTerminal Growth,X%,,,,\nWACC,X%,,,,\n\nBULL CASE ASSUMPTIONS (section header - merge across columns A:G)\nAssumption,FY1,FY2,FY3,FY4,FY5\nRevenue Growth (%),X%,X%,X%,X%,X%\nEBIT Margin (%),X%,X%,X%,X%,X%\nTerminal Growth,X%,,,,\nWACC,X%,,,,\n```\n\n**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.**\n\n**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.\n\n### Correct Row Planning Process\n\n**1. Write ALL headers and labels FIRST:**\n```csv\nRow,Content\n1,[Company Name] DCF Model\n2,Ticker | Date | Year End\n4,Case Selector\n7,KEY ASSUMPTIONS\n26,Assumption headers\n27-31,Growth assumptions\n...,...\n```\n\n**2. Write ALL section dividers and blank rows**\n\n**3. THEN write formulas using the locked row positions**\n\n**4. Test formulas immediately after creation**\n\n**Think of it like construction:**\n- Good: Pour foundation, then build walls (stable structure)\n- Bad: Build walls, then pour foundation (walls collapse)\n\n**Excel version:**\n- Good: Add headers, then write formulas (formulas stable)\n- Bad: Write formulas, then add headers (formulas break)\n\n### Correct Sensitivity Table Implementation\n\n**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.\n\n**Programmatic Population with Formulas:**\n\nEach 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).\n\n**Implementation approach - CONCRETE EXAMPLE:**\n\n**Table Structure — 5×5 grid (ODD dimensions, base case centered):**\n\nIf the model's base WACC = 9.0% and base terminal growth = 3.0%, build the axes symmetrically around those values:\n\n```csv\nWACC vs Terminal Growth,  2.0%,  2.5%,  3.0%,  3.5%,  4.0%\n              8.0%,       [fml], [fml], [fml], [fml], [fml]\n              8.5%,       [fml], [fml], [fml], [fml], [fml]\n              9.0%,       [fml], [fml], [★  ], [fml], [fml]   ← middle row = base WACC\n              9.5%,       [fml], [fml], [fml], [fml], [fml]\n             10.0%,       [fml], [fml], [fml], [fml], [fml]\n                                   ↑\n                          middle col = base terminal g\n```\n\n**★ = the center cell.** Its formula output MUST equal the model's actual implied share price (from the valuation summary). Apply the medium-blue fill (`#BDD7EE`) and bold font to this cell so the base case is visually anchored.\n\n**Rule for axis values:** `axis_values = [base - 2*step, base - step, base, base + step, base + 2*step]` — symmetric around the base, odd count guarantees a center.\n\n**Formula Pattern - Cell B88 (WACC=8.0%, Terminal Growth=2.0%):**\n\nThe formula in B88 should recalculate the implied price using:\n- WACC from row header: `$A88` (8.0%)\n- Terminal Growth from column header: `B$87` (2.0%)\n\n**Recommended approach:** Reference the main DCF calculation but substitute these values.\n\n**Example formula structure:**\n`=([SUM of PV FCFs using $A88 as discount rate] + [Terminal Value using B$87 as growth rate and $A88 as WACC] - [Net Debt]) / [Shares]`\n\n**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.\n\n**Python implementation pattern:**\n```python\n# Pseudocode for populating sensitivity table\nfor row_idx, wacc_value in enumerate(wacc_range):\n    for col_idx, term_growth_value in enumerate(term_growth_range):\n        # Build formula that uses wacc_value and term_growth_value\n        formula = f\"=\u003cDCF recalc using {wacc_value} and {term_growth_value}\u003e\"\n        ws.cell(row=start_row+row_idx, column=start_col+col_idx).value = formula\n```\n\n**The sensitivity tables must work immediately when the model is opened, with no manual steps required from the user.**\n\n\u003c/correct_patterns\u003e\n\n\u003ccommon_mistakes\u003e\n\nThis section contains all the WRONG patterns to avoid when building DCF models.\n\n### WRONG: Simplified Sensitivity Table Approximations or Placeholder Text\n\n**Don't use linear approximations:**\n\n```\n// WRONG - Linear approximation\nB97: =B88*(1+(0.096-0.116))    // Assumes linear relationship\n\n// WRONG - Division shortcut\nB105: =B88/(1+(E48-0.07))      // Doesn't recalculate full DCF\n```\n\n**Don't leave placeholder text:**\n```\n// WRONG - Placeholder note\n\"Note: Use Excel Data Table feature (Data → What-If Analysis → Data Table) to populate sensitivity tables.\"\n\n// WRONG - Empty cells\n[leaving cells blank because \"this is complex\"]\n```\n\n**Don't confuse terminology:**\n- ❌ \"Sensitivity tables need Excel's Data Table feature\" (NO - that's a specific Excel tool we can't use)\n- ✅ \"Sensitivity tables are simple grids with formulas in each cell\" (YES - this is what we build)\n\n**Why these shortcuts are wrong:**\n- Linear approximation formulas don't actually recalculate the DCF - they just apply simple math adjustments\n- The relationships are not linear, so the results will be inaccurate\n- Placeholder text requires manual user intervention\n- Model is not immediately usable when delivered\n- Not professional or client-ready\n- Empty cells = incomplete deliverable\n\n**Common rationalization to REJECT:**\n\"Writing 75+ formulas feels complex, so I'll leave a note for the user to complete it manually.\"\n\n**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.\n\n**Instead:** Populate every sensitivity cell with formulas that recalculate the full DCF for that specific combination of assumptions\n\n### WRONG: Missing Cell Comments\n\n**Don't do this:**\n- Create all hardcoded inputs without comments\n- Think \"I'll add them later\"\n- Write \"TODO: add source\"\n- Leave blue inputs without documentation\n\n**Why it's wrong:**\n- Can't verify where data came from\n- Fails xlsx skill requirements\n- Not audit-ready\n- Wastes time fixing later\n\n**Instead:** Add cell comment AS EACH hardcoded value is created\n\n### WRONG: Formula Row References Off\n\n**Symptom:**\nThe FCF section references wrong assumption rows:\n`D\u0026A:  =E29*$E$34    // Should be $E$21, but referencing wrong row`\n`CapEx: =E29*$E$41   // Should be $E$22, but row shifted`\n\n**Why this happens:**\n1. Formulas written first\n2. Then headers inserted\n3. All row references shifted\n4. Now formulas point to wrong cells → #REF! errors\n\n**Instead:** Lock row layout FIRST, then write formulas\n\n### WRONG: Single Row for Each Assumption Across Scenarios\n\n**Don't structure assumptions like this:**\n```csv\nAssumption,Bear,Base,Bull\nRevenue Growth FY1,10%,13%,16%\nRevenue Growth FY2,9%,12%,15%\n```\nThis vertical layout makes it hard to see the progression across years within each scenario.\n\n**Why it's wrong:**\n- Makes it difficult to see assumptions evolving across years within each scenario\n- Harder to compare scenario assumptions across full projection period\n- Less intuitive for reviewing scenario logic\n\n**Instead:**\n- Create separate blocks for each scenario (Bear, Base, Bull)\n- Within each block, show assumptions horizontally across projection years\n- This makes each scenario's assumptions easier to review as a cohesive set\n\n### WRONG: No Borders\n\n**Don't deliver a model without borders:**\n- No section delineation\n- All cells blend together\n- Hard to read and unprofessional\n\n**Why it's wrong:**\n- Not client-ready\n- Difficult to navigate\n- Looks amateur\n\n**Instead:** Add borders around all major sections\n\n### WRONG: Wrong Font Colors or No Font Color Distinction\n\n**Don't do this:**\n- All text is black\n- Only use fill colors (no font color changes)\n- Mix up which cells are blue vs black\n\n**Why it's wrong:**\n- Can't distinguish inputs from formulas\n- Auditing becomes impossible\n- Violates xlsx skill requirements\n\n**Instead:** Blue text for ALL hardcoded inputs, black text for ALL formulas, green for sheet links\n\n### WRONG: Operating Expenses Based on Gross Profit\n\n**Don't do this:**\n`S\u0026M: =E33*0.15    // E33 = Gross Profit (WRONG)`\n\n**Why it's wrong:**\n- Operating expenses scale with revenue, not gross profit\n- Produces unrealistic margin progression\n- Not how businesses actually operate\n\n**Instead:**\n`S\u0026M: =E29*0.15    // E29 = Revenue (CORRECT)`\n\n### TOP 5 ERRORS SUMMARY\n\n1. **Formula row references off** → Define ALL row positions BEFORE writing formulas\n2. **Missing cell comments** → Add comments AS cells are created, not at end\n3. **Simplified sensitivity tables** → Populate all cells with full DCF recalc formulas, not approximations\n4. **Scenario block references wrong** → Ensure IF formulas pull from correct Bear/Base/Bull blocks\n5. **No borders** → Add professional section borders for client-ready appearance\n\nIn addition, be aware of these errors:\n\n### WACC Calculation Errors\n- Mixing book and market values in capital structure\n- Using equity beta instead of asset/unlevered beta incorrectly\n- Wrong tax rate application to cost of debt\n- Incorrect risk-free rate (must use current 10Y Treasury)\n- Failure to adjust for net debt vs net cash position\n\n### Growth Assumption Flaws\n- Terminal growth \u003e WACC (creates infinite value)\n- Projection growth rates inconsistent with historical performance\n- Ignoring industry growth constraints\n- Revenue growth not aligned with unit economics\n- Margin expansion without operational justification\n\n### Terminal Value Mistakes\n- Using wrong growth method (perpetuity vs exit multiple)\n- Terminal value \u003e80% of enterprise value (suggests over-reliance)\n- Inconsistent terminal margins with steady state assumptions\n- Wrong discount period for terminal value\n\n### Cash Flow Projection Errors\n- Operating expenses based on gross profit instead of revenue\n- D\u0026A/CapEx percentages misaligned with business model\n- Working capital changes not properly calculated\n- Tax rate inconsistency between years\n- NOPAT calculation errors\n\n**These errors are the most common. Re-read this section before starting any DCF build.**\n\n\u003c/common_mistakes\u003e\n\n## Excel File Creation\n\n**This skill uses the `xlsx` skill for all spreadsheet operations.** The xlsx skill provides:\n- Standardized formula construction rules\n- Number formatting conventions\n- Automated formula recalculation via `recalc.py` script\n- Comprehensive error checking and validation\n\nAll Excel files created by this skill must follow xlsx skill requirements, including zero formula errors and proper recalculation.\n\n## Quality Rubric\n\nEvery DCF model must maximize for:\n1. **Realistic revenue and margin assumptions** based on historical performance\n2. **Appropriate cost of capital calculation** with proper CAPM methodology\n3. **Comprehensive sensitivity analysis** showing valuation ranges\n4. **Clear terminal value calculation** with supporting rationale\n5. **Professional model structure** enabling scenario analysis\n6. **Transparent documentation** of all key assumptions\n\n## Input Requirements\n\n### Minimum Required Inputs\n1. **Company identifier**: Ticker symbol or company name\n2. **Growth assumptions**: Revenue growth rates for projection period (or \"use consensus\")\n3. **Optional parameters**:\n   - Projection period (default: 5 years)\n   - Scenario cases (Bear/Base/Bull growth and margin assumptions)\n   - Terminal growth rate (default: 2.5-3.0%)\n   - Specific WACC inputs if not using CAPM\n\n## Excel Model Structure\n\n### Sheet Architecture\n\nCreate **two sheets**:\n\n1. **DCF** - Main valuation model with sensitivity analysis at bottom\n2. **WACC** - Cost of capital calculation\n\n**CRITICAL**: Sensitivity tables go at the BOTTOM of the DCF sheet (not on a separate sheet). This keeps all valuation outputs together.\n\n### Formula Recalculation (MANDATORY)\n\nAfter creating or modifying the Excel model, **recalculate all formulas** using the recalc.py script from the xlsx skill:\n\n```bash\npython recalc.py [path_to_excel_file] [timeout_seconds]\n```\n\nExample:\n```bash\npython recalc.py AAPL_DCF_Model_2025-10-12.xlsx 30\n```\n\nThe script will:\n- Recalculate all formulas in all sheets using LibreOffice\n- Scan ALL cells for Excel errors (#REF!, #DIV/0!, #VALUE!, #NAME?, #NULL!, #NUM!, #N/A)\n- Return detailed JSON with error locations and counts\n\n**Expected output format:**\n```json\n{\n  \"status\": \"success\",           // or \"errors_found\"\n  \"total_errors\": 0,              // Total error count\n  \"total_formulas\": 42,           // Number of formulas in file\n  \"error_summary\": {}             // Only present if errors found\n}\n```\n\n**If errors are found**, the output will include details:\n```json\n{\n  \"status\": \"errors_found\",\n  \"total_errors\": 2,\n  \"total_formulas\": 42,\n  \"error_summary\": {\n    \"#REF!\": {\n      \"count\": 2,\n      \"locations\": [\"DCF!B25\", \"DCF!C25\"]\n    }\n  }\n}\n```\n\n**Fix all errors** and re-run recalc.py until status is \"success\" before delivering the model.\n\n### Formatting Standards\n\n**IMPORTANT**: Follow the xlsx skill for formula construction rules and number formatting conventions. The DCF skill adds specific visual presentation standards.\n\n**Color Scheme - Two Layers**:\n\n**Layer 1: Font Colors (MANDATORY from xlsx skill)**\n- **Blue text (RGB: 0,0,255)**: ALL hardcoded inputs (stock price, shares, historical data, assumptions)\n- **Black text (RGB: 0,0,0)**: ALL formulas and calculations\n- **Green text (RGB: 0,128,0)**: Links to other sheets (WACC sheet references)\n\n**Layer 2: Fill Colors — Professional Blue/Grey Palette (Default unless user specifies otherwise)**\n- **Keep it minimal** — use only blues and greys for fills. Do NOT introduce greens, yellows, oranges, or multiple accent colors. A model with too many colors looks amateurish.\n- **Default fill palette:**\n  - **Section headers**: Dark blue (RGB: 31,78,121 / `#1F4E79`) background with white bold text\n  - **Sub-headers/column headers**: Light blue (RGB: 217,225,242 / `#D9E1F2`) background with black bold text\n  - **Input cells**: Light grey (RGB: 242,242,242 / `#F2F2F2`) background with blue font — or just white with blue font if you want maximum minimalism\n  - **Calculated cells**: White background with black font\n  - **Output/summary rows** (per-share value, EV, etc.): Medium blue (RGB: 189,215,238 / `#BDD7EE`) background with black bold font\n- **That's it — 3 blues + 1 grey + white.** Resist the urge to add more.\n- User-provided templates or explicit color preferences ALWAYS override these defaults.\n\n**How the layers work together:**\n- Input cell: Blue font + light grey fill = \"Hardcoded input\"\n- Formula cell: Black font + white background = \"Calculated value\"\n- Sheet link: Green font + white background = \"Reference from another sheet\"\n- Key output: Black bold font + medium blue fill = \"This is the answer\"\n\n**Font color tells you WHAT it is (input/formula/link). Fill color tells you WHERE you are (header/data/output).**\n\n### Border Standards (REQUIRED for Professional Appearance)\n\n**Thick borders** (1.5pt) around major sections:\n- KEY INPUTS section\n- PROJECTION ASSUMPTIONS section\n- 5-YEAR CASH FLOW PROJECTION section\n- TERMINAL VALUE section\n- VALUATION SUMMARY section\n- Each SENSITIVITY ANALYSIS table\n\n**Medium borders** (1pt) between sub-sections:\n- Company Details vs Historical Performance\n- Growth Assumptions vs EBIT Margin vs FCF Parameters\n\n**Thin borders** (0.5pt) around data tables:\n- Scenario assumption tables (Bear | Base | Bull | Selected)\n- Historical vs projected financials matrix\n\n**No borders:** Individual cells within tables (keep clean, scannable)\n\n**Borders are mandatory** - models without professional borders are not client-ready.\n\n**Number Formats** (follows xlsx skill standards):\n- **Years**: Format as text strings (e.g., \"2024\" not \"2,024\")\n- **Percentages**: `0.0%` (one decimal place)\n- **Currency**: `$#,##0` for millions; `$#,##0.00` for per-share - ALWAYS specify units in headers (\"Revenue ($mm)\")\n- **Zeros**: Use number formatting to make all zeros \"-\" (e.g., `$#,##0;($#,##0);-`)\n- **Large numbers**: `#,##0` with thousands separator\n- **Negative numbers**: `(#,##0)` in parentheses (NOT minus sign)\n\n**Cell Comments (MANDATORY for all hardcoded inputs)**:\n\nPer the xlsx skill, ALL hardcoded values must have cell comments documenting the source. Format: \"Source: [System/Document], [Date], [Reference], [URL if applicable]\"\n\n**CRITICAL**: Add comments AS CELLS ARE CREATED. Do not defer to the end.\n\n### DCF Sheet Detailed Structure\n\n**Section 1: Header**\n```csv\nRow,Content\n1,[Company Name] DCF Model\n2,Ticker: [XXX] | Date: [Date] | Year End: [FYE]\n3,Blank\n4,Case Selector Cell (1=Bear 2=Base 3=Bull)\n5,Case Name Display (formula: =IF([Selector]=1\"Bear\"IF([Selector]=2\"Base\"\"Bull\")))\n```\n\n**Section 2: Market Data (NOT case dependent)**\n```csv\nItem,Value\nCurrent Stock Price,$XX.XX\nShares Outstanding (M),XX.X\nMarket Cap ($M),[Formula]\nNet Debt ($M),XXX [or Net Cash if negative]\n```\n\n**Section 3: DCF Scenario Assumptions**\n\nCreate separate assumption blocks for each scenario (Bear, Base, Bull) with DCF-specific assumptions (Revenue Growth %, EBIT Margin %, Tax Rate %, D\u0026A % 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 `\u003ccorrect_patterns\u003e` section \"Correct Assumption Table Structure\" for the exact layout.\n\n**Section 4: Historical \u0026 Projected Financials**\n\n**Reference a consolidation column (e.g., \"Selected Case\") that pulls from scenario blocks**, not scattered IF formulas in every projection row.\n\n```csv\nIncome Statement ($M),2020A,2021A,2022A,2023A,2024E,2025E,2026E\nRevenue,XXX,XXX,XXX,XXX,[=E29*(1+$E$10)],[=F29*(1+$E$11)],[=G29*(1+$E$12)]\n  % growth,XX%,XX%,XX%,XX%,[=E29/D29-1],[=F29/E29-1],[=G29/F29-1]\n,,,,,,\nGross Profit,XXX,XXX,XXX,XXX,[=E29*E33],[=F29*F33],[=G29*G33]\n  % margin,XX%,XX%,XX%,XX%,[=E33/E29],[=F33/F29],[=G33/G29]\n,,,,,,\nOperating Expenses:,,,,,,,\n  S\u0026M,XXX,XXX,XXX,XXX,[=E29*0.15],[=F29*0.14],[=G29*0.13]\n  R\u0026D,XXX,XXX,XXX,XXX,[=E29*0.12],[=F29*0.11],[=G29*0.10]\n  G\u0026A,XXX,XXX,XXX,XXX,[=E29*0.08],[=F29*0.07],[=G29*0.07]\n  Total OpEx,XXX,XXX,XXX,XXX,[=E36+E37+E38],[=F36+F37+F38],[=G36+G37+G38]\n,,,,,,\nEBIT,XXX,XXX,XXX,XXX,[=E33-E39],[=F33-F39],[=G33-G39]\n  % margin,XX%,XX%,XX%,XX%,[=E41/E29],[=F41/F29],[=G41/G29]\n,,,,,,\nTaxes,(XX),(XX),(XX),(XX),[=E41*$E$24],[=F41*$E$24],[=G41*$E$24]\n  Tax rate,XX%,XX%,XX%,XX%,[=E43/E41],[=F43/F41],[=G43/G41]\n,,,,,,\nNOPAT,XXX,XXX,XXX,XXX,[=E41-E43],[=F41-F43],[=G41-G43]\n```\n\n**Key Formula Pattern**:\n- Revenue growth: `=E29*(1+$E$10)` where $E$10 is consolidation column for Year 1 growth\n- NOT: `=E29*(1+IF($B$6=1,$B$10,IF($B$6=2,$C$10,$D$10)))`\n\nThis approach is cleaner, easier to audit, and prevents formula errors by centralizing the scenario logic.\n\n**Section 5: Free Cash Flow Build**\n\n**CRITICAL**: Verify row references point to the CORRECT assumption rows. Test formulas immediately after creation.\n\n```csv\nCash Flow ($M),2020A,2021A,2022A,2023A,2024E,2025E,2026E\nNOPAT,XXX,XXX,XXX,XXX,[=E45],[=F45],[=G45]\n(+) D\u0026A,XXX,XXX,XXX,XXX,[=E29*$E$21],[=F29*$E$21],[=G29*$E$21]\n    % of Rev,XX%,XX%,XX%,XX%,[=E58/E29],[=F58/F29],[=G58/G29]\n(-) CapEx,(XX),(XX),(XX),(XX),[=E29*$E$22],[=F29*$E$22],[=G29*$E$22]\n    % of Rev,XX%,XX%,XX%,XX%,[=E60/E29],[=F60/F29],[=G60/G29]\n(-) Δ NWC,(XX),(XX),(XX),(XX),[=(E29-D29)*$E$23],[=(F29-E29)*$E$23],[=(G29-F29)*$E$23]\n    % of Δ Rev,XX%,XX%,XX%,XX%,[=E62/(E29-D29)],[=F62/(F29-E29)],[=G62/(G29-F29)]\n,,,,,,\nUnlevered FCF,XXX,XXX,XXX,XXX,[=E57+E58-E60-E62],[=F57+F58-F60-F62],[=G57+G58-G60-G62]\n```\n\n**Row reference examples** (based on layout planning):\n- $E$21 = D\u0026A % assumption (consolidation column, row 21)\n- $E$22 = CapEx % assumption (consolidation column, row 22)\n- $E$23 = NWC % assumption (consolidation column, row 23)\n- E29 = Revenue for year (row 29)\n- E45 = NOPAT for year (row 45)\n\n**Before writing formulas**: Confirm these row numbers match the actual layout. Test one column, then copy across.\n\n**Section 6: Discounting \u0026 Valuation**\n```csv\nDCF Valuation,2024E,2025E,2026E,2027E,2028E,Terminal\nUnlevered FCF ($M),XXX,XXX,XXX,XXX,XXX,\nPeriod,0.5,1.5,2.5,3.5,4.5,\nDiscount Factor,0.XX,0.XX,0.XX,0.XX,0.XX,\nPV of FCF ($M),XXX,XXX,XXX,XXX,XXX,\n,,,,,,\nTerminal FCF ($M),,,,,,,XXX\nTerminal Value ($M),,,,,,,XXX\nPV Terminal Value ($M),,,,,,,XXX\n,,,,,,\nValuation Summary ($M),,,,,,\nSum of PV FCFs,XXX,,,,,\nPV Terminal Value,XXX,,,,,\nEnterprise Value,XXX,,,,,\n(-) Net Debt,(XX),,,,,\nEquity Value,XXX,,,,,\n,,,,,,\nShares Outstanding (M),XX.X,,,,,\nIMPLIED PRICE PER SHARE,$XX.XX,,,,,\nCurrent Stock Price,$XX.XX,,,,,\nImplied Upside/(Downside),XX%,,,,,\n```\n\n### WACC Sheet Structure\n\n```csv\nCOST OF EQUITY CALCULATION,,\nRisk-Free Rate (10Y Treasury),X.XX%,[Yellow input]\nBeta (5Y monthly),X.XX,[Yellow input]\nEquity Risk Premium,X.XX%,[Yellow input]\nCost of Equity,X.XX%,[Calculated blue]\n,,\nCOST OF DEBT CALCULATION,,\nCredit Rating,AA-,[Yellow input]\nPre-Tax Cost of Debt,X.XX%,[Yellow input]\nTax Rate,XX.X%,[Link to DCF sheet]\nAfter-Tax Cost of Debt,X.XX%,[Calculated blue]\n,,\nCAPITAL STRUCTURE,,\nCurrent Stock Price,$XX.XX,[Link to DCF]\nShares Outstanding (M),XX.X,[Link to DCF]\nMarket Capitalization ($M),\"X,XXX\",[Calculated]\n,,\nTotal Debt ($M),XXX,[Yellow input]\nCash \u0026 Equivalents ($M),XXX,[Yellow input]\nNet Debt ($M),XXX,[Calculated]\n,,\nEnterprise Value ($M),\"X,XXX\",[Calculated]\n,,\nWACC CALCULATION,Weight,Cost,Contribution\nEquity,XX.X%,X.X%,X.XX%\nDebt,XX.X%,X.X%,X.XX%\n,,\nWEIGHTED AVERAGE COST OF CAPITAL,X.XX%,[Green output]\n```\n\n**Key WACC Formulas:**\n```\nMarket Cap = Price × Shares\nNet Debt = Total Debt - Cash\nEnterprise Value = Market Cap + Net Debt\nEquity Weight = Market Cap / EV\nDebt Weight = Net Debt / EV\nWACC = (Cost of Equity × Equity Weight) + (After-tax Cost of Debt × Debt Weight)\n```\n\n### Sensitivity Analysis (Bottom of DCF Sheet)\n\n**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.\n\n**Location**: Rows 87+ on DCF sheet (NOT a separate sheet)\n\n**Three sensitivity tables, vertically stacked:**\n\n1. **WACC vs Terminal Growth** (rows 87-100) - 5x5 grid = 25 cells with formulas\n2. **Revenue Growth vs EBIT Margin** (rows 102-115) - 5x5 grid = 25 cells with formulas\n3. **Beta vs Risk-Free Rate** (rows 117-130) - 5x5 grid = 25 cells with formulas\n\n**Total formulas to write: 75** (this is required, not optional)\n\n**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.\n\n**Table Setup:**\n1. Create table structure with row/column headers (the assumption values to test)\n2. Populate EVERY data cell with a formula that:\n   - Uses the row header value (e.g., WACC = 9.0%)\n   - Uses the column header value (e.g., Terminal Growth = 3.0%)\n   - Recalculates the full DCF with those specific assumptions\n   - Returns the implied share price for that scenario\n3. All cells must contain working formulas when delivered\n4. Format cells with conditional formatting: Green scale for higher values, red scale for lower values\n5. Bold the base case cell\n6. Leave 1-2 blank rows between tables\n\n**No manual intervention required** - the sensitivity tables must be fully functional when the user opens the file.\n\n## Case Selector Implementation\n\n**Three-Case Framework:**\n\n### Bear Case\n- Conservative revenue growth (low end of historical range)\n- Margin compression or no expansion\n- Higher WACC (risk premium increase)\n- Lower terminal growth rate\n- Higher CapEx assumptions\n\n### Base Case\n- Consensus or management guidance revenue growth\n- Moderate margin expansion based on operating leverage\n- Current market-implied WACC\n- GDP-aligned terminal growth (2.5-3.0%)\n- Standard CapEx assumptions\n\n### Bull Case\n- Optimistic revenue growth (high end of projections)\n- Significant margin expansion\n- Lower WACC (reduced risk premium)\n- Higher terminal growth (3.5-5.0%)\n- Reduced CapEx intensity\n\n**Formula Implementation:**\n\n**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.\n\n**Recommended pattern (using INDEX):**\n`=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)\n\n**Then reference the consolidation column** in all projections:\n`Revenue Year 1: =D29*(1+$E$10)` where $E$10 is the consolidation column value for Year 1 growth.\n\nThis approach centralizes scenario logic, making the model easier to audit and maintain.\n\n## Deliverables Structure\n\n**File naming**: `[Ticker]_DCF_Model_[Date].xlsx`\n\n**Two sheets**:\n1. **DCF** - Complete model with Bear/Base/Bull cases + three sensitivity tables at bottom (WACC vs Terminal Growth, Revenue Growth vs EBIT Margin, Beta vs Risk-Free Rate)\n2. **WACC** - Cost of capital calculation\n\n**Key features**: Case selector (1/2/3), consolidation column with INDEX/OFFSET formulas, color-coded cells, cell comments on all inputs, professional borders\n\n## Best Practices\n\n### Model Construction\n1. **Build incrementally**: Complete each section before moving to next\n2. **Test as building**: Enter sample numbers to verify formulas\n3. **Use consistent structure**: Similar calculations follow similar patterns\n4. **Comment complex formulas**: Add notes for unusual calculations\n5. **Build in checks**: Sum checks and balance checks where applicable\n\n### Documentation\n1. **Document all assumptions**: Explain reasoning behind key inputs\n2. **Cite data sources**: Note where each data point came from\n3. **Explain methodology**: Describe any non-standard approaches\n4. **Flag uncertainties**: Highlight areas with limited visibility\n\n### Quality Control\n1. **Cross-check calculations**: Verify math in multiple ways\n2. **Stress test assumptions**: Run sensitivity to ensure model is robust\n3. **Peer review**: Have someone else check formulas\n4. **Version control**: Save versions as work progresses\n\n## Common Variations\n\n### High-Growth Technology Companies\n- Longer projection period (7-10 years)\n- Higher initial growth rates (20-30%)\n- Significant margin expansion over time\n- Higher WACC (12-15%)\n- Model unit economics (users, ARPU, etc.)\n\n### Mature/Stable Companies\n- Shorter projection period (3-5 years)\n- Modest growth rates (GDP +1-3%)\n- Stable margins\n- Lower WACC (7-9%)\n- Focus on cash generation and capital allocation\n\n### Cyclical Companies\n- Model through economic cycle\n- Normalize margins at mid-cycle\n- Consider trough and peak scenarios\n- Adjust beta for cyclicality\n\n### Multi-Segment Companies\n- Separate DCFs for each business unit\n- Different growth rates and margins by segment\n- Sum-of-parts valuation\n- Consider synergies\n\n## Troubleshooting\n\n**If you encounter errors or unreasonable results, read [TROUBLESHOOTING.md](./TROUBLESHOOTING.md) for detailed debugging guidance.**\n\n## Workflow Integration\n\n### At Start of DCF Build\n\n1. **Gather market data**:\n   - Check for available MCP servers for current market data\n   - Use web search/fetch for stock prices, beta, and other market metrics\n   - Request from user if specific data is needed\n\n2. **Gather historical financials**:\n   - Check for available MCP servers (Daloopa, etc.)\n   - Request from user if not available via MCP\n   - Manual extraction from 10-Ks if necessary\n\n3. **Begin model construction** using the DCF methodology detailed in this skill\n\n### During Model Construction\n\n1. **Build Excel model** using openpyxl with formulas (not hardcoded values)\n2. **Follow xlsx skill conventions** for formula construction and formatting\n3. **Apply fill colors only if requested** by user or if specific brand guidelines are provided\n\n### Before Delivering Model (MANDATORY)\n\n1. **Verify structure**:\n   - Scenario blocks for Bear/Base/Bull with assumptions across projection years\n   - Case selector functional with formulas referencing correct scenario blocks\n   - Sensitivity tables at bottom of DCF sheet (not separate sheet)\n   - Font colors: Blue inputs, black formulas, green sheet links\n   - Cell comments on ALL hardcoded inputs\n   - Professional borders around major sections\n\n2. **Recalculate formulas**: Run `python recalc.py model.xlsx 30`\n\n3. **Check output**:\n   - If `status` is `\"success\"` → Continue to step 4\n   - If `status` is `\"errors_found\"` → Check `error_summary` and read [TROUBLESHOOTING.md](./TROUBLESHOOTING.md) for debugging guidance\n\n4. **Fix errors and re-run recalc.py** until status is \"success\"\n\n5. **Spot-check formulas**:\n   - Test one FCF formula - does it reference the correct assumption rows?\n   - Change case selector - does the consolidation column update properly?\n   - Verify revenue formulas reference consolidation column (not nested IF formulas)\n\n6. **Deliver model**\n\n### Available Data Sources\n\n- **MCP servers**: If configured (Daloopa for historical financials)\n- **Web search/fetch**: For current stock prices, beta, and market data\n- **User-provided data**: Historical financials, consensus estimates\n- **Manual extraction**: SEC EDGAR filings as fallback\n\n## Final Output Checklist\n\nBefore delivering DCF model:\n\n**Required:**\n- Run `python recalc.py model.xlsx 30` until status is \"success\" (zero formula errors)\n- Two sheets: DCF (with sensitivity at bottom), WACC\n- Font colors: Blue=inputs, Black=formulas, Green=sheet links\n- Cell comments on ALL hardcoded inputs\n- Sensitivity tables fully populated with formulas\n- Professional borders around major sections\n\n**Validation:**\n- OpEx based on revenue (not gross profit)\n- Terminal value 50-70% of EV\n- Terminal growth \u003c WACC\n- Tax rate 21-28%\n- File naming: `[Ticker]_DCF_Model_[Date].xlsx`","TROUBLESHOOTING.md":"# DCF Model Troubleshooting Guide\n\n**When to read this file:** If recalc.py shows errors OR valuation results seem unreasonable OR case selector not working properly.\n\n## Model Returns Error Values\n\n### #REF! Errors\n- Usually caused by formulas referencing wrong rows after headers were inserted\n- Solution: Rebuild with correct row references, or start over following layout planning\n- Prevention: Define all row positions BEFORE writing formulas\n\n### #DIV/0! Errors\n- Division by zero or empty cells\n- Solution: Add IF statements to handle zeros: `=IF([Divisor]=0,0,[Numerator]/[Divisor])`\n\n### #VALUE! Errors\n- Wrong data type in calculation (text instead of number)\n- Solution: Verify all inputs are formatted as numbers\n\n## Valuation Seems Unreasonable\n\n### Implied price far too high\n- Check terminal value isn't \u003e80% of EV\n- Verify terminal growth \u003c WACC\n- Review if growth assumptions are realistic\n- Consider if margins are too optimistic\n\n### Implied price far too low\n- Verify net debt vs net cash is correct\n- Check if WACC is too high\n- Review if projections are too conservative\n- Consider if terminal growth is too low\n\n## Case Selector Not Working\n\n### Consolidation column not updating when switching scenarios\n- Verify case selector cell contains 1, 2, or 3\n- Check INDEX/OFFSET formulas reference correct row range and selector cell\n- Ensure absolute references ($B$6) are used for selector\n- Test by manually changing the selector cell and verifying projection values update\n","requirements.txt":"# DCF Model Builder - Python Dependencies\n\n# Excel file handling\nopenpyxl\u003e=3.0.0\n\n# HTTP requests\nrequests\u003e=2.28.0\n","scripts/validate_dcf.py":"#!/usr/bin/env python3\n\"\"\"\nDCF Model Validation Script\nValidates Excel DCF models for formula errors and common DCF mistakes\n\"\"\"\n\nimport sys\nimport json\nfrom pathlib import Path\nfrom typing import Optional\n\n\nclass DCFModelValidator:\n    \"\"\"Validates DCF models for errors and quality issues\"\"\"\n\n    def __init__(self, excel_path: str):\n        try:\n            import openpyxl\n        except ImportError:\n            raise ImportError(\"openpyxl not installed. Run: pip install openpyxl\")\n\n        self.excel_path = excel_path\n        self.openpyxl = openpyxl\n\n        if not Path(excel_path).exists():\n            raise FileNotFoundError(f\"File not found: {excel_path}\")\n\n        self.workbook_formulas = openpyxl.load_workbook(excel_path, data_only=False)\n        self.workbook_values = openpyxl.load_workbook(excel_path, data_only=True)\n        self.errors = []\n        self.warnings = []\n        self.info = []\n        \n    def validate_all(self) -\u003e dict:\n        \"\"\"\n        Run all validation checks\n\n        Returns:\n            Dict with validation results\n        \"\"\"\n        from datetime import datetime\n\n        self.check_sheet_structure()\n        self.check_formula_errors()\n        self.check_dcf_logic()\n\n        results = {\n            'file': self.excel_path,\n            'validation_date': datetime.now().isoformat(),\n            'status': 'PASS' if len(self.errors) == 0 else 'FAIL',\n            'error_count': len(self.errors),\n            'warning_count': len(self.warnings),\n            'errors': self.errors,\n            'warnings': self.warnings,\n            'info': self.info\n        }\n\n        return results\n    \n    def check_sheet_structure(self):\n        \"\"\"Verify required sheets exist\"\"\"\n        required_sheets = ['DCF', 'WACC', 'Sensitivity']\n        sheet_names = self.workbook_values.sheetnames\n\n        for sheet in required_sheets:\n            if sheet not in sheet_names:\n                self.warnings.append(f\"Recommended sheet missing: {sheet}\")\n            else:\n                self.info.append(f\"Found sheet: {sheet}\")\n\n    def check_formula_errors(self):\n        \"\"\"Check for Excel formula errors in all sheets\"\"\"\n        excel_errors = ['#VALUE!', '#DIV/0!', '#REF!', '#NAME?', '#NULL!', '#NUM!', '#N/A']\n        error_details = {err: [] for err in excel_errors}\n        total_errors = 0\n        total_formulas = 0\n\n        for sheet_name in self.workbook_values.sheetnames:\n            ws_values = self.workbook_values[sheet_name]\n            ws_formulas = self.workbook_formulas[sheet_name]\n\n            for row in ws_values.iter_rows():\n                for cell in row:\n                    formula_cell = ws_formulas[cell.coordinate]\n\n                    # Count formulas\n                    if formula_cell.value and isinstance(formula_cell.value, str) and formula_cell.value.startswith('='):\n                        total_formulas += 1\n\n                    # Check for errors\n                    if cell.value is not None and isinstance(cell.value, str):\n                        for err in excel_errors:\n                            if err in cell.value:\n                                location = f\"{sheet_name}!{cell.coordinate}\"\n                                error_details[err].append(location)\n                                total_errors += 1\n                                self.errors.append(f\"{err} at {location}\")\n                                break\n\n        # Add summary info\n        self.info.append(f\"Total formulas: {total_formulas}\")\n        if total_errors == 0:\n            self.info.append(\"✓ No formula errors found\")\n        else:\n            self.errors.append(f\"Total formula errors: {total_errors}\")\n\n        return error_details, total_errors\n    \n    def check_dcf_logic(self):\n        \"\"\"Validate DCF-specific logic and calculations\"\"\"\n        self._check_terminal_growth_vs_wacc()\n        self._check_wacc_range()\n        self._check_terminal_value_proportion()\n\n    def _check_terminal_growth_vs_wacc(self):\n        \"\"\"Critical check: Terminal growth must be less than WACC\"\"\"\n        try:\n            dcf_sheet = self.workbook_values['DCF']\n\n            terminal_growth = None\n            wacc = None\n\n            # Search for terminal growth and WACC values\n            for row in dcf_sheet.iter_rows(max_row=100, max_col=20):\n                for cell in row:\n                    if cell.value and isinstance(cell.value, str):\n                        cell_str = cell.value.lower()\n                        if 'terminal' in cell_str and 'growth' in cell_str:\n                            # Look for value in adjacent cells\n                            for offset in range(1, 5):\n                                adjacent = dcf_sheet.cell(cell.row, cell.column + offset).value\n                                if isinstance(adjacent, (int, float)) and 0 \u003c adjacent \u003c 1:\n                                    terminal_growth = adjacent\n                                    break\n                        if 'wacc' in cell_str and wacc is None:\n                            for offset in range(1, 5):\n                                adjacent = dcf_sheet.cell(cell.row, cell.column + offset).value\n                                if isinstance(adjacent, (int, float)) and 0 \u003c adjacent \u003c 1:\n                                    wacc = adjacent\n                                    break\n\n            if terminal_growth is not None and wacc is not None:\n                if terminal_growth \u003e= wacc:\n                    self.errors.append(\n                        f\"CRITICAL: Terminal growth ({terminal_growth:.2%}) \u003e= WACC ({wacc:.2%}). \"\n                        \"This creates infinite value and is mathematically invalid.\"\n                    )\n                else:\n                    self.info.append(\n                        f\"✓ Terminal growth ({terminal_growth:.2%}) \u003c WACC ({wacc:.2%})\"\n                    )\n            else:\n                self.warnings.append(\"Could not locate terminal growth and WACC values\")\n\n        except KeyError:\n            self.warnings.append(\"DCF sheet not found\")\n        except Exception as e:\n            self.warnings.append(f\"Could not validate terminal growth vs WACC: {str(e)}\")\n\n    def _check_wacc_range(self):\n        \"\"\"Check if WACC is in reasonable range\"\"\"\n        try:\n            wacc_sheet = self.workbook_values.get('WACC') or self.workbook_values['DCF']\n            wacc = None\n\n            for row in wacc_sheet.iter_rows(max_row=100, max_col=20):\n                for cell in row:\n                    if cell.value and isinstance(cell.value, str):\n                        if 'wacc' in cell.value.lower():\n                            for offset in range(1, 5):\n                                adjacent = wacc_sheet.cell(cell.row, cell.column + offset).value\n                                if isinstance(adjacent, (int, float)) and 0 \u003c adjacent \u003c 1:\n                                    wacc = adjacent\n                                    break\n\n            if wacc is not None:\n                if wacc \u003c 0.05 or wacc \u003e 0.20:\n                    self.warnings.append(\n                        f\"WACC ({wacc:.2%}) is outside typical range (5%-20%). Verify calculation.\"\n                    )\n                else:\n                    self.info.append(f\"✓ WACC ({wacc:.2%}) in reasonable range\")\n            else:\n                self.warnings.append(\"Could not locate WACC value\")\n\n        except Exception as e:\n            self.warnings.append(f\"Could not validate WACC range: {str(e)}\")\n\n    def _check_terminal_value_proportion(self):\n        \"\"\"Check if terminal value is reasonable proportion of enterprise value\"\"\"\n        try:\n            dcf_sheet = self.workbook_values['DCF']\n\n            terminal_value = None\n            enterprise_value = None\n\n            for row in dcf_sheet.iter_rows(max_row=200, max_col=20):\n                for cell in row:\n                    if cell.value and isinstance(cell.value, str):\n                        cell_str = cell.value.lower()\n                        if 'terminal' in cell_str and 'value' in cell_str and 'pv' in cell_str:\n                            for offset in range(1, 5):\n                                adjacent = dcf_sheet.cell(cell.row, cell.column + offset).value\n                                if isinstance(adjacent, (int, float)) and adjacent \u003e 0:\n                                    terminal_value = adjacent\n                                    break\n                        if 'enterprise' in cell_str and 'value' in cell_str:\n                            for offset in range(1, 5):\n                                adjacent = dcf_sheet.cell(cell.row, cell.column + offset).value\n                                if isinstance(adjacent, (int, float)) and adjacent \u003e 0:\n                                    enterprise_value = adjacent\n                                    break\n\n            if terminal_value is not None and enterprise_value is not None and enterprise_value \u003e 0:\n                proportion = terminal_value / enterprise_value\n                if proportion \u003e 0.80:\n                    self.warnings.append(\n                        f\"Terminal value is {proportion:.1%} of EV (typically should be 50-70%). \"\n                        \"Model may be over-reliant on terminal assumptions.\"\n                    )\n                elif proportion \u003c 0.40:\n                    self.warnings.append(\n                        f\"Terminal value is {proportion:.1%} of EV (typically should be 50-70%). \"\n                        \"Check if terminal assumptions are too conservative.\"\n                    )\n                else:\n                    self.info.append(f\"✓ Terminal value is {proportion:.1%} of EV\")\n            else:\n                self.warnings.append(\"Could not locate terminal value and enterprise value\")\n\n        except Exception as e:\n            self.warnings.append(f\"Could not validate terminal value proportion: {str(e)}\")\n    \n\n\ndef validate_dcf_model(excel_path: str) -\u003e dict:\n    \"\"\"\n    Validate a DCF model Excel file\n\n    Args:\n        excel_path: Path to Excel DCF model\n\n    Returns:\n        Dict with validation results\n    \"\"\"\n    validator = DCFModelValidator(excel_path)\n    return validator.validate_all()\n\n\ndef main():\n    \"\"\"Command-line interface\"\"\"\n    if len(sys.argv) \u003c 2:\n        print(\"Usage: python validate_dcf.py \u003cexcel_file\u003e [output.json]\")\n        print(\"\\nValidates DCF model for:\")\n        print(\"  - Formula errors (#REF!, #DIV/0!, etc.)\")\n        print(\"  - Terminal growth \u003c WACC (critical)\")\n        print(\"  - WACC in reasonable range (5-20%)\")\n        print(\"  - Terminal value proportion of EV (40-80%)\")\n        print(\"\\nReturns JSON with errors, warnings, and info\")\n        print(\"\\nExample: python validate_dcf.py model.xlsx\")\n        print(\"Example: python validate_dcf.py model.xlsx results.json\")\n        sys.exit(1)\n\n    excel_file = sys.argv[1]\n    output_file = sys.argv[2] if len(sys.argv) \u003e 2 else None\n\n    try:\n        results = validate_dcf_model(excel_file)\n\n        # Print results\n        print(json.dumps(results, indent=2))\n\n        # Save to file if requested\n        if output_file:\n            with open(output_file, 'w') as f:\n                json.dump(results, f, indent=2)\n\n        # Exit with error code if validation failed\n        sys.exit(0 if results['status'] == 'PASS' else 1)\n\n    except Exception as e:\n        error_result = {\n            'file': excel_file,\n            'status': 'ERROR',\n            'error': str(e)\n        }\n        print(json.dumps(error_result, indent=2))\n        sys.exit(1)\n\n\nif __name__ == \"__main__\":\n    main()\n"},"import":{"commit_sha":"9affc6e683bbaf66361058117027cf5a50bf1861","imported_at":"2026-05-18T20:09:40Z","license_text":"\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n","owner":"anthropics","repo":"anthropics/financial-services","source_url":"https://github.com/anthropics/financial-services/tree/9affc6e683bbaf66361058117027cf5a50bf1861/plugins/agent-plugins/model-builder/skills/dcf-model"}},"content_hash":[223,136,100,123,220,85,141,248,8,173,0,31,233,233,29,183,157,217,3,46,7,172,98,226,24,238,170,188,134,29,101,150],"trust_level":"unsigned","yanked":false}
