InteractiveThe Spotify model, all 14 tabs›

Finance tools I built, with the models and checks behind them.

A diligence pack that builds a linked three-statement DCF and a report around it, tested so far on Spotify. A reverse DCF that backs out the growth and exit multiple a share price implies. A basket builder that tracks the S&P 500 with 75 names instead of 500. A screener that puts one ticker's prices, fundamentals, drawdowns, street views and news on one dashboard.

Jason Zou · Economics and Philosophy, University of Chicago. Each tool runs as a Claude skill or plugin; I set the method, the modelling rules and the checks.

stock-diligence · excerptsGitHub
Walkthrough
Full diligence on TICKER

A walkthrough of the current version's phases and call budgets, not a recording of a run. The Spotify test runs used the plugin's single-agent order.

Excerpts of the plugin's files. Click any file, switch tabs, or play a full, express or refresh run.

Tools

What I built.

Each tool produces a workbook, a report or a dashboard. Each section below says which parts the tool automates and which it leaves to judgment.

Stock diligence pack · Claude plugin v1.0.4

Each run builds a linked three-statement DCF, an assumptions memo and a report.

Getting up to speed on a public company means rebuilding three statements, a debt schedule and the bridge from enterprise value to equity, choosing the multiples that fit the business, and working out how it allocates capital. Most of that is assembly, and the model is where errors hide. The plugin does the assembly, checks its own model, and leaves the view on the company to the reader. Spotify is the only company it has been run on end to end so far.

TICKER_DCF.xlsx
14 tabs

Linked three-statement DCF.

Four scenarios switched from one cell, a debt schedule, the EV-to-equity bridge, both terminal methods side by side, three live sensitivity grids, and a Checks tab that has to read ALL OK. Open the Spotify model below.

TICKER_diligence_report.docx · .pdf
13 sections

The report.

A fixed order from the tear sheet to theses and deciding questions, plus seven appendices. Standard mode aims for about 50 pages, warns outside 30 to 70 and fails the build above 100; extensive mode has no cap.

TICKER_DCF_assumptions_memo.docx

Assumptions memo.

Each lever gets its own subsection with a values table (last actual, FY1, FY2, FY5, FY10), its anchor, the mechanism and what would change it. Eight pages for Spotify.

MANIFEST.md

Manifest.

Every file with its as-of date and source, the tools that failed, the data gaps, and the open items the reviewers left for the reader.

two_pager.docx · .pdf

Internal two-pager.

A fixed internal two-page format. A script rejects it unless it is exactly two pages with the second at least 85% full.

filings/ · earnings digest · industry primer · tear sheet

Companion pack, on request.

Filings with a reading order, an earnings digest of the last four to eight calls at one page each, an industry primer, and a one-page tear sheet.

SPOT_DCF.xlsx · rebuilt from the plugin and recalculated

The Spotify model. Switch the case, click any cell.

Spotify's workbook as dcf_build.py writes it from the plugin's Spotify input file, recalculated in LibreOffice for all four cases: 14 tabs, 1,984 formulas, zero errors. One input is corrected from the file as shipped (the notes gain is entered net of FX, as its label says), and the Cover's 52-week range is left blank because the price history file is not bundled. Click a cell to read its formula, and click a reference to follow it to another tab.

SPOT_DCF.xlsx
Case (Cover!B4)
Value per share$515.03−5.2% vs $543.17 on 4 Sep 2026ALL OK
Cover!B4fx1
Click a cell to see its formula and follow its references.
Loading the workbook…

Colours follow banking convention, as in the file: blue for hard-coded inputs, black for formulas, green for links from another sheet, yellow for key levers and outputs. The Bear case raises one CHECK flag and no FAIL, which the rules allow.

Case study · Spotify (SPOT) · valuation date 4 Sep 2026

Built by running it on one company and fixing what broke.

Spotify was the test case. Every mistake found in a run was also fixed in the tool, so the next run would not repeat it. The figures below come from the Spotify test runs and the rebuilt workbook, at a share price of $543.17.

$515.03Street-case value per share, perpetuity growth method
$654.11Same case with an 18x EV/EBIT exit multiple. That implies 5.6% perpetuity growth against 3.0%, so the exit value reads as rich and the perpetuity value is the headline.
$601.83Management case, built from the May 2026 Investor Day targets
$290–$721Range across the bear and bull cases, perpetuity growth method
3.6%Perpetuity growth the price implies on the Street cash flows
12.5xExit EV/EBIT the price implies in year ten
11.3xExit EV/EBIT implied by the model's own terminal value, a cross-check on the 18x
€81.0bnStreet-case enterprise value, 59% of it in the terminal value

What Spotify's price implies.

On the workbook's simplified revenue and margin grid, the $543 price needs roughly 12% revenue growth for ten years and a 23 to 24% terminal operating margin. The Street DCF lands below the price and the management case above it; with bull at 10% and bear at 20%, the price needs about 60% weight on the management case.

The report turns this into a monitoring dashboard of seven KPIs, each with its Street-case path and the level at which the bear case becomes the base case.

See every case in the workbook.

Street-case calibration.

ModelConsensusGap
FY2026E revenue, €m19,53219,5380.0%
FY2027E revenue, €m22,22822,309−0.4%
FY2026E diluted EPS, €12.1412.30−1.3%
FY2027E diluted EPS, €14.6215.51−5.7%
Cost of equity10.3%

The rule is revenue within ±1% and EPS within about ±5% of consensus before any other case is written; FY2027E EPS sits just outside that band. Residual EPS gaps usually come from finance income, tax or share count rather than operations. Consensus is Yahoo Finance's as of 4 Sep 2026. Open the Consensus tab.

What the validation loop caught.

A clean recalculation only proves that formulas evaluate. These came from reading values back and reconciling them line by line.

01

A €154m balance-sheet break. A fair-value gain on the exchangeable notes (€184m less €30m of FX) sat in net income with no reversal in operating cash flow. It was traced to the line rather than plugged. Replay it in the Checks tab.

02

A patch applied to the wrong builder file, so the buyback inputs never changed. Since then a fix counts only once its value has been read back, not when the errors disappear.

03

Yahoo's free-cash-flow field was off by about 2.5x. It showed $1.5bn against the company's €3.3bn TTM, about $3.8bn. FCF yield is now computed from company figures.

What the runs taught the tool.

  • Check the earnings calendar before searching the news. It confirmed 11 of the 15 largest five-year moves as earnings days in one step.
  • Pick the benchmark for the episode. From 3 to 5 February 2026 Spotify fell about 19% while a software index fell about 4% and 4.6% on two of those days, although the stock's trailing beta to software was only 0.4. The regression said idiosyncratic; the news said an AI-driven software selloff. The report writes down that reconciliation.
  • Label the basis on every table. A standardised provider showed FY2023 operating income of −€199m against −€446m as reported.
  • Look for a mechanism before calling a miss a demand signal. A payroll tax that moves with the share price explained two guidance misses and two beats.
  • Write the summary and the tear sheet last, from final numbers.

How the tool got here.

  • Two Spotify test runsA 56-page standard run, and a 174-page extensive run with three audit rounds that is now the reference for extensive mode. Both ran in the plugin's single-agent order, with the review roles taken one after another.
  • Rebuilt for speedA full run was taking about a day. Numeric exhibits moved into scripts, the report got a fixed skeleton, the DCF became driven by one input file with one-command validation, research agents got call budgets, and express and refresh modes were added.
  • Split into twelve skillsEach component can be called on its own, including the internal two-pager.

Estimating what is not disclosed.

Some figures an investment case needs never appear in the filings. The tool estimates them only when an identity links them to disclosed numbers, labels each one "(est.)", and documents the method in an appendix.

// six steps, Appendix G
1 identity net adds = gross adds − churn × base
2 anchors every disclosed data point, old ones included
3 ranges low / most likely / high, each sourced
4 propagate Monte Carlo, triangular draws
5 calibrate against a disclosed total
6 sensitivity which assumption dominates

For Spotify, an assumed monthly churn of 2.5% to 5.0% (most likely 3.5%) went through 20,000 draws to size gross subscriber additions and acquisition cost, each result labelled (est.).

The same tool also produced short five-page notes on two private companies, Mistral AI and Cognition.

Inside the diligence pack

How a run is organised, and what the report contains.

One coordinating agent, the orchestrator, handles the data, the merge and the render, so every number has one source. Five analyst subagents do the research, the valuation analyst builds and validates the model, and five reviewer subagents check the result. This describes the current version; the Spotify test runs used the plugin's single-agent order.

How a run works.

Scroll through a full run, or click a phase in the window.

Full diligence run · schematic
  • Phase 0 · scope confirmed, defaults recorded
  • Phase 1 · filings, decks, transcripts, prices, statements
  • Phase 2 · event_scan, technicals, margin_bridge
  • Phase 3 · five analyst subagents in parallel
business≤25 fetches or searchesevents≤20 searchesstreet≤15 searchesstatements≤10 fetchesvaluation≤3 build cycles
  • Phase 4 · workbook validated, zero errors, ALL OK
  • Phase 5 · report assembled, rendered and checked
  • Phase 6 · review panel, fixes, manifest
valuation and returns · sections 0, 7, 12capital structure · sections 4, 11estimates and guidance · sections 5, 6, 7, 9red team · every sectionQA · checklist
✓ Checks tab reads ALL OK · files delivered
Phases 0 to 2 · orchestrator

Scope and data.

Confirms the listing, currency, fiscal year and EDGAR CIK, and records defaults instead of asking questions. Pulls filings, decks and transcripts, ten years of prices and five of statements, then runs the event-scan, technicals and margin-bridge scripts. Every gap is written down, never filled in silently.

Phase 3 · five analyst subagents in parallel

Five analysts, each with a limit.

Each reads only its own playbook and inputs, writes to a fixed file, and returns a path plus a five-line summary. Nothing is merged from chat text. Four work to call budgets; the valuation analyst builds the model and is capped at three build cycles.

Business≤25 fetches or searchesEvents≤20 searchesStreet≤15 searchesStatements≤10 fetchesValuation≤3 build cycles
Phases 4 and 5 · valuation analyst, then orchestrator

Validate, assemble, render.

The valuation analyst validates the workbook first, with zero formula errors, ALL OK and a grid centre equal to the DCF value per share. Then the orchestrator merges script-generated exhibits and research blocks in a fixed section order and renders a portrait Word report. Conflicts go by source rank: filing, then deck, then standardised feed.

Phase 6 · five reviewer subagents in parallel

A review panel.

Five reviewer subagents, each prompted as a different reader, read only the sections their brief covers and return at most ten findings, ranked and tagged FAIL or IMPROVE. None of them fixes anything; the orchestrator does.

Valuation and returns0 · 7 · 12Capital structure4 · 11Estimates and guidance5 · 6 · 7 · 9Red teamallQAchecklist
Delivery

Fix, re-render, ship.

Up to three rounds, later ones scoped to what changed. Whatever is left goes into the manifest as open items, and general lessons are listed there as changes to make in the tool.

The report, section by section.

The order is fixed in report_skeleton.json, so every company comes out in the same shape. Open a section to see what fills it: exhibits that scripts compute, and research blocks written by a subagent or the orchestrator. The organising question is what the price already assumes, and what evidence would revise it.

  • Every figure carries its basis, source and as-of date. Standardised and reported figures are reconciled when they differ by more than 2%.
  • Estimates are labelled and shown with a range. Figures the filings do not give are built from an accounting identity, calibrated to a disclosed total, and reported with the 10th to 90th percentile of a Monte Carlo.
  • Theses are written as arguments, with the case and its evidence, what must be true and which model line it touches, then the deciding question and what would refute it.
  • No recommendation. The report ends with the deciding questions and a pre-mortem written from two years ahead.
report_skeleton.json order · qa_gates.py page budgets
exhibit, computed by a scriptresearch block, written by a subagent or the orchestrator

Page figures are the per-section budgets for standard mode, not the Spotify run's page counts. qa_gates.py checks them against the rendered PDF, along with placeholders, stray em dashes, label-style sentences and landscape pages.

The analysis rules in the playbooks.

They live in the plugin's reference playbooks, so every run applies them the same way.

Multiples chosen for the business model.

BusinessPrimary multiples
Asset-light, trivial D&AEV/EBIT, P/FCF
Capex or content heavyEV/EBIT or EV/(EBITDA − capex)
Heavy stock-based compGAAP EBIT; never adjusted EBITDA that adds SBC back
Different gross margins from peersEV/Gross profit next to EV/Sales
Negative earningsEV/Sales and EV/GP, adjusted for growth
Banks and insurersP/TBV and P/E with ROTE; P/BV with ROE
REITsP/FFO and implied cap rate
CyclicalsEV/normalised EBIT and P/B at mid-cycle

Quality of earnings, with thresholds.

CheckFlag when
CFO / net income< 1.0 two years running
Accruals, (NI − CFO) / assets> 5% or rising
Receivables vs revenue growthgap > 10 pts
Deferred vs subscription revenue growthgap < −10 pts
Capex / D&A< 0.7, or > 2 without growth
Effective vs statutory tax rategap > 10 pts, unexplained
"Non-recurring" itemsin 3 of 5 years
Goodwill / total assets> 30%
EBIT / interest< 3x
Net debt / EBITDA> 3x, or rising into a downturn

Margin bridges.

Each line as a share of revenue, each operating line as a share of gross profit, each below-the-line item as a share of operating income, and each profit line as a share of the one above, with a waterfall. The largest drag on margin is then valued in currency.

Why the stock moved.

The 15 largest one-day moves over five years, every run of three or more days above 10% and every drawdown deeper than 15%. Each daily move is split into sector move and idiosyncratic residual. Earnings days are confirmed first and the rest traced to a primary source. "Unattributed" is allowed; a forced cause is not.

Insiders and buybacks.

Authorisations, execution by quarter against the share price, and a share-count bridge net of SBC. Identical share counts on a schedule, paired with same-day option exercises, are flagged as 10b5-1 plan sales, not a signal.

Scenario weighting and monitoring.

A probability-weighted value at illustrative weights, the weight on the management case needed to reach the price, the return skew, a twelve-month roll-forward of each scenario, a capital-allocation capacity block, and a monitoring dashboard whose break levels are the bear-case inputs.

stock-diligence-report
The full pack, with report, workbook, memo and manifest"Full diligence on SPOT" · "express diligence on SPOT"↵ open SKILL.md in the editor above
dcf-only
Workbook, assumptions memo and comps tab"Build a Street DCF for SPOT with the assumptions memo"↵ open SKILL.md in the editor above
event-attribution
Five years of large moves, each with a source"Why did SPOT fall in February 2026?"↵ open SKILL.md in the editor above
comps-valuation
Peers on the right multiple, own-history statistics"Comps for SPOT, which multiple should I use?"↵ open SKILL.md in the editor above
statements-analysis
Statements, margin bridges, quality of earnings"Margin bridge and quality of earnings for SPOT"↵ open SKILL.md in the editor above
business-understanding
How the company makes money and what is underappreciated"How does Spotify actually make money?"↵ open SKILL.md in the editor above
insider-buyback-check
Buybacks, Form 4 ledger, holders, short interest"Are Spotify insiders selling? What about the buyback?"↵ open SKILL.md in the editor above
street-view
Consensus, targets, revisions, long and short theses"What does the street assume for SPOT?"↵ open SKILL.md in the editor above
technicals-check
Positioning against ten years of the stock's own history"Is SPOT stretched technically?"↵ open SKILL.md in the editor above
audit-panel
The five reviewers on any existing report or memo"Audit this memo"↵ open SKILL.md in the editor above
refresh-diligence
Roll a workspace forward a quarter; rebuild only what changed"Refresh the SPOT diligence after the next print"↵ open SKILL.md in the editor above
internal-two-pager
Two-page write-up from the package, or asks for each input"Write a two-pager on MU"↵ open SKILL.md in the editor above
No skill matches that. Try "dcf", "audit" or "insider".

Run one part without the full pack.

Most questions do not need the full pack. Each of the twelve skills runs on its own with the same rules, scripts and QA gates, and reuses the company's work folder if one exists. Search the list and press Enter to open that skill's instructions in the editor at the top.

ModeWhat changes
StandardAbout 50 pages, per-section page budgets, hard cap of 100
ExtensiveNo page cap; every product, broker, move and period in full
ExpressThree analysts and the QA auditor only; report, workbook, memo, manifest
RefreshReuses the work folder, reruns data and exhibits, rebuilds only affected sections

What is automated. What stays human.

Automated

  • Pulling filings, prices, statements, estimates, earnings dates, insider transactions, holders and FX
  • Every numeric exhibit and chart, generated by scripts; figures Claude copies from filings go into one input file that the checks then test
  • Building the linked model from that input file, recalculating it, and running four scenarios and three toggles through the checks
  • Drafting the scenario deviations, and adapting the revenue build when a business does not fit the subscription template (the valuation subagent)
  • Drafting sections in parallel, merging from files, rendering, and gating the PDF
  • A five-reader review before delivery, with findings ranked and tagged FAIL or IMPROVE

Human

  • The view on the company; the pack deliberately makes no recommendation
  • Scenario weights and any price target; the tool's weights are marked illustrative
  • Reviewing and signing off the scenario deviations, any adapted revenue build, and the explanation of the gap between the DCF and the price
  • Deciding which of the reviewers' open items matter
GitHub profile12 skills · 10 subagents · 15 scripts · 13 reference playbooks
Reverse DCF · the valuation engine inside the pack

What the share price already assumes.

When the model and the market disagree, the useful question runs the other way: what growth and margin would you have to believe to justify today's price? The workbook solves for that in closed form, with no goal seek. Whether the answer is believable is the analyst's call.

How it works.

  1. Calibrate a Street case first. Year-one and year-two revenue land within ±1% of consensus, EPS within about ±5%, and year five is anchored to management's long-term targets before the path fades. The valuation subagent then drafts management, bull and bear cases as explicit deviations from Street, each with a one-line reason.
  2. Solve what the price requires. Holding the explicit forecast fixed, back out the terminal value the market is paying for, then convert it into an implied perpetual growth rate and an implied exit EV/EBIT, in closed form.
  3. Map the pairs that clear the price. A simplified grid of ten-year revenue CAGR against terminal EBIT margin, with the margin fading linearly from the last actual year, shades each pair against the price.
  4. Prove the grids are the model. The centre of the WACC × growth grid must equal the DCF value per share to the cent, and switching the terminal method to exit multiple must reproduce the side-by-side exit value.
// market-implied block, DCF tab
Market EV = market cap ÷ roll-forward − net bridge
TV required = (Market EV − PV explicit UFCF) × (1 + WACC)t
implied g = (TV × WACC − UFCFN) ÷ (TV + UFCFN)
implied exit = TV required ÷ EBITN
// solves UFCF × (1+g) ÷ (WACC − g) = TV for g
scripts/dcf_build.py · excerpt, abridged
# Market-implied expectations: what today's price assumes,# holding the explicit forecastr_mev = vrow("Market enterprise value (€m) = market cap − net bridge",             f"={I(ROW_MCAP)}/C{r_roll}-C{r_net}")r_mtv = vrow("Terminal value required to justify the price (€m)",             f"=(C{r_mev}-C{r_sumpv})*(1+C{r_wacc})^C{r_ptv}")r_mg  = vrow("Market-implied perpetual growth rate",             f"=(C{r_mtv}*C{r_wacc}-{N}{DC['ufcf']})/(C{r_mtv}+{N}{DC['ufcf']})", PCT)r_mx  = vrow(f"Market-implied exit EV/EBIT ({PROJ[9]})",             f"=C{r_mtv}/{N}{DC['ebit']}", MULT)
# Grid 3: revenue CAGR x terminal EBIT margin (simplified engine)def f_rev(cg, m):    pv = f"SUMPRODUCT({R0}*(1+{cg})^{T_}*(({M0}+({m}-{M0})*{T_}/10)*(1-{TX})+{NR})*{ST_}*(1+{WW})^(-{PD_}))"    uN = f"({R0}*(1+{cg})^10*({m}*(1-{TX})+{NR}))"    tv = f"{uN}*(1+{GG})/({WW}-{GG})/(1+{WW})^{PTV_G}"    return f"=(({pv}+{tv}+{NETB})*{ROLLF})/{SH}*{FX}" cagrs   = [0.08, 0.10, 0.12, 0.14, 0.16]margins = [0.16, 0.20, 0.24, 0.28, 0.32]
Try it · fictional XMPL · grid 3's formula, simplified (no stub or bridge)
above the pricenear itbelow itclosest to the priceCAGR* growth the price requires at that margin

$1.0bn starting revenue, margin fading linearly from 12%, capex 2% of revenue above D&A, 25% tax, 100m shares, no net debt, end-of-year discounting. Cells toward the lower right are worth more than the price; toward the upper left, less.

Modelling rules the DCF builder enforces.

  • Interest on opening balances, so there is no circularity and no iteration setting.
  • SBC is a real cost by default. The add-back is a toggle; using it means diluting the share count by hand, which the model does not do.
  • Diluted shares by the treasury stock method, with every unvested RSU included.
  • Stub period, mid-year convention and roll-forward to the valuation date, so value is compared like for like with today's price.
  • Discount rate in the cash-flow currency. Euro cash flows use a Bund-based rate.
  • Exit multiple chosen by the comps rule, EV/EBIT for asset-light businesses and EV/EBITDA only where D&A is large and not matched by recurring capex.
  • Every projection row is one formula copied across all forecast columns; no result is hard-coded.

Automated

  • Calibrating the Street case to consensus revenue and EPS, and recording the gap to management targets
  • Drafting the management, bull and bear deviations, each with a reason (the valuation subagent)
  • Solving implied growth and the implied exit multiple from the price
  • Building all three grids as live formulas, and proving grids 1 and 2 tie to the model

Human

  • Judging whether the implied growth and margin are achievable for this business
  • Reviewing and signing off the scenario deviations
  • Checking the memo's explanation of the gap between the Street DCF and the price, the first thing a reader will ask about
Direct indexing basket builder

Track the S&P 500 with 75 names instead of 500.

Owning an index through its individual stocks lets a client tilt away from names they do not want and harvest losses, but holding all 500 is impractical for most accounts. The question is how few names you can hold while still tracking closely, and how much tracking error each cut adds. At an asset management firm I used to work at, I built agentic workflows to screen instruments and a dashboard for the CIO. I also used this builder there to produce a 100-name S&P 500 basket and a 20-name NASDAQ-100 basket for the CIO, each with stratified sampling, quarterly rebalancing and a full backtest.

How a basket is built.

  1. Resolve the inputs. The defaults are the S&P 500 with SPY as proxy, 75 names, quarterly rebalancing, a five-year backtest and constrained market-cap weights. A basket size given by the user is used exactly.
  2. Build the eligible universe. Drop names without continuous history over the horizon or below the liquidity and size floors, and record the exclusions.
  3. Stratify by sector. Partition by GICS sector and keep the largest names in each sector until its index weight is filled.
  4. Refine for tracking error. Fill the remaining slots with the names that most reduce ex-ante tracking error within the constraints (sector tolerance, maximum weight per name, minimum liquidity, turnover cap).
  5. Weight explicitly. Market-cap-informed weights, capped per name and renormalised to sector targets. Equal weighting only when chosen on purpose.
  6. Backtest and stress the size. Daily adjusted-close returns, then tracking error and correlation at two or more other basket sizes so the trade-off is visible.
direct_index_basket_SPY_75n_YYYYMMDD.xlsx · layout example
Layout example · placeholder names and weights, not a run
NameSectorBasketIndexTiltRole
Name AInfo. Technology6.10%5.40%+0.70%Mega-cap anchor
Name BInfo. Technology5.20%4.90%+0.30%Mega-cap anchor
Name CHealth Care3.80%2.60%+1.20%Sector proxy
Name DFinancials3.50%2.20%+1.30%Sector proxy
Name EIndustrials2.40%1.10%+1.30%Tracking-error filler
…
75 names100.00%

Sorted by weight. Weights must sum to exactly 1.0000; any floating-point residual is reconciled into the largest weight before the file is written.

Layout example · illustrative weights
SectorBasketIndexDelta
Information Technology31.2%31.8%−0.6%
Financials13.4%13.1%+0.3%
Health Care10.2%10.0%+0.2%
Consumer Discretionary10.3%10.4%−0.1%
…
All 11 sectors100.0%100.0%0.0%

Every sector in the index must appear, so an empty sector shows as a visible gap rather than silently disappearing.

Example values from the tool's output schema, not a run · click a size

Bar length is annualised tracking error, so shorter is better. Smaller baskets are simpler but track worse. Click a size to highlight it.

MetricHow it is computed
Tracking errorAnnualised volatility of daily basket − index returns
CorrelationDaily returns, full period, plus a 60-day rolling series (mean, min, max)
Beta and R²Basket returns regressed on index returns
Up and down captureBasket move relative to the index in up and down markets
Volatility and drawdown gapsBasket minus index, annualised volatility and max drawdown
Beat diagnosticsMonthly, rolling-12m, up-market and down-market beat rates. Backward-looking only; never an objective

The Meta sheet records the as-of date, benchmark and constituent count, basket size, construction and weighting method, rebalance frequency, backtest window, a methodology paragraph and the disclaimers.

Each run also delivers a JSON payload with the same data and a fixed dashboard with a KPI strip, cumulative performance, rolling correlation, cumulative active return, sector bars, composition, tracking and beat diagnostics, methodology and risks.

Automated

  • Screening the index for history, liquidity and size
  • Sector stratification, tracking-error fill and capped weights
  • The backtest, the size sensitivity and the five-sheet workbook
  • Refusing to run without a price source; prices, weights and statistics are never made up

Human

  • Choosing the basket size and the constraints
  • Deciding whether the tracking error is acceptable for the client
  • Any tax or wash-sale call, which the tool never makes
  • Weighing the stated limits (survivorship bias from current constituents, no trading costs or taxes, drift out of sample)
Stock screener · Claude skill v6.3

The same six-tab dashboard for every stock.

A first pass on a name should cover the same ground every time: price and returns against the market, five years of fundamentals, drawdowns, what the street thinks and what the news says. By hand it is slow and never quite the same twice. The screener fills a fixed dashboard for any stock or ETF, six tabs for a stock and five for an ETF. I have run it on LEU, CRDO, PSTG, STLD, MTSI, XRX, CLSK and GE, with data from LSEG Refinitiv, which the skill requires, and yfinance.

StockScreenerDashboard.jsx · XMPL
XMPLExample Corp, a fictional ticker
Illustrative · synthetic data · the dashboard's layout with made-up numbers
$50.00
Weekly close and volume, five years
Returns

The real dashboard sets each return beside the S&P 500 over the same window, measured from fixed reference dates.

Header and metrics

Price and change, six headline metrics, and returns against the S&P 500 over 1M, 3M, 6M, YTD, 1Y, 3Y and 5Y.

Price and volume

Five years of weekly bars (about 260) with volume. Hover the chart to read any week.

The business

Company overview, revenue streams, a geographic revenue split and a value-chain diagram that shades the stages the company operates in.

Drawdown from the running high
Drawdowns deeper than 10%

Drawdowns and risk

Underwater chart, maximum drawdown with peak, trough and recovery dates, and every drawdown deeper than 10% (7% for broad ETFs).

Momentum

1, 3, 6 and 12-month returns and a 0 to 100 score, with a fixed order for resolving conflicting signals.

Fundamentals, five years

Profitability, growth, valuation, capital return, and a cash flow and leverage section with at least eleven metrics, each with a status, a five-year chart and a note on what drove it.

Monthly close, 10-month average and MACD histogram
Regime, by the skill's rule table

Monthly chart

Sixty monthly closes with a 10-month moving average, from eight years of history so the MACD (12, 26, 9) has a full warm-up.

Regime

One of six labels from price against the moving average, the MACD sign and whether the histogram is expanding, with a conviction score from 25 to 95.

Catalyst months

Months that moved more than two standard deviations or 8%, each explained from a search and marked on the chart.

Price targets against the current price
Rating mix
Checks before it renders

    Consensus

    Rating mix and estimates. Rating counts must add up to the number of analysts.

    Target distribution

    A box plot of price targets against the current price; quartiles must sit inside the low-high range.

    Recent actions

    Twenty or more analyst actions from the last 90 days, each with its thesis and a source link.

    Sentiment

    Twenty or more articles, each scored for sentiment, relevance, urgency and confidence, weighted by source tier and recency.

    Themes and keywords

    Three to five bullish and bearish themes, and a keyword panel checked against a finance-specific word list.

    Articles

    A paginated reader with a link to every piece. Fewer than eight articles is labelled limited coverage.

    Data sources

    Grouped as filings, company, data providers, news and other. Primary sources rank above secondary ones and every link must resolve; records without a URL are dropped.

    Data warnings

    Every gap stated plainly ("no analyst consensus available", "limited news coverage") instead of a filled-in guess.

    Cash flow and leverage, defined.

    Each metric carries five yearly values and the reason it moved.

    EBITDA = operating income + D&A
    UFCF = EBIT × (1 − t) + D&A − capex − ΔNWC
    LFCF = CFO − capex
    NWC = current assets − current liabilities
    FCF yield = LFCF ÷ market cap
    Debt / EBITDA, capex / revenue, EBITDA margin
    // NWC is the screener's simple definition: it still
    // includes cash and short-term debt
    // N/M: P/E when EPS ≤ 0, EV/EBITDA when EBITDA < 0,
    // P/B when book value < 0, ROE when average equity < 0

    How the screener checks itself.

    • Claude only supplies the data. The dashboard is a fixed template; the skill fills one data block and never writes layout, so no two tickers look different.
    • The template computes the indicators (moving averages, MACD, drawdown series) from raw prices and recomputes the MACD statistics itself.
    • Missing data stays missing. A gap is left null with a warning; prices, ratios and URLs are never invented.
    • The skill works through a 23-item checklist before rendering, covering drawdown dates in order, a 1M reference date 25 to 35 days back, rating counts that add up and regional splits near 100%.
    • Claude's judgments are marked as judgments. Sentiment scores, value-chain explanations and regime labels are flagged as analysis, not data.

    Automated

    • Numbers from LSEG Refinitiv and yfinance; qualitative context from web search
    • Returns, drawdowns, momentum, fundamentals and the cash-flow metrics
    • Validation, warnings and filling the fixed template

    Human

    • Reading the output and deciding whether the name deserves real work
    • Judging ambiguous news; cost cuts are scored "mixed" because only a person can say whether they are strategic or forced
    • Any buy or sell view; the screener never gives one
    Two smaller tools

    A substitute finder and a MACD test.

    correlated-substitutes · v0.1.0

    Correlated substitutes finder

    Given one stock, it returns the three liquid US stocks whose returns behave most like it. I built it as research support for tax-loss harvesting in direct-indexed accounts, where a sold name needs a close stand-in.

    • The universe is the S&P 1500 plus large NASDAQ names, screened for liquidity first (a 90-day median of $25m a day and 250k shares)
    • It uses two years of daily log returns, never price levels
    • Candidates are ranked on a composite, not raw correlation
    score = 0.45 × correlation
    + 0.20 × R²
    + 0.15 × (1 − |β − 1|)
    + 0.10 × min 60-day rolling correlation
    + 0.10 × liquidity score
    // the β and rolling-correlation terms are clipped to 0 to 1
    Try the score · enter a candidate's statistics

    Labels map the full-period correlation, from Very High (0.90 and above) through High, Moderate and Weak to Poor (below 0.40). A name whose rolling correlation collapses below 0.3 while its full-period figure is above 0.7 is flagged. The tool never says whether a substitute is "substantially identical" for wash-sale purposes; that is a tax call.

    macd-test · v0.1.0

    MACD signal test

    Has the monthly MACD crossover worked on this stock over the last five years? A 585-line Python script pulls eight years of monthly prices, computes MACD (12, 26, 9) and a 10-month average, and scores every crossover on its 3, 6 and 12-month forward return. A crossover reversed within two months counts as a failure.

    Try the verdict · enter a backtest's results
    VerdictRule, applied top-down
    ReliableN ≥ 8, 3m hit rate ≥ 60%, expectancy ≥ 3% on bull or bear signals, false signals ≤ 25%
    Mixedfewer than 8 signals (low sample)
    InaccurateN ≥ 8, 3m hit rate < 40% and false signals ≥ 35%
    Mixedeverything else

    The thresholds are set before the data is seen, and the dashboard shows the inputs next to the verdict so it can be audited. It tests whether a common chart signal holds up; it is not a trading tool.

    How I build these

    Principles behind the tools.

    The tools differ, and these principles are written into their instructions. The first, fourth and fifth apply to the diligence pack.

    01 Diligence pack

    Scripts compute the numbers.

    Every numeric exhibit and chart comes from a script. Figures Claude copies from filings go into one input file that the checks then test, and the language model writes the readings, reconciliations and arguments around them.

    02

    No invented numbers.

    Unknown is "n/d", recalled is "[verify]", missing is null with a warning. Estimates carry "(est.)", a method and a range. Every figure has a basis, a source and an as-of date.

    03

    Fixed templates.

    Dashboards, the report skeleton and the workbook layout are fixed. Each run mostly fills data, so output is consistent between companies, cheaper to produce and easy to audit.

    04 Diligence pack

    The model has to tie.

    Balance sheets balance, cash ties, equity rolls forward and grids reproduce the model. Seventeen checks run on every workbook; eleven can fail it, and the Street case must read ALL OK before it is delivered.

    05 Diligence pack

    Review before delivery.

    Five reviewer subagents, each prompted as a different reader, return ranked findings tagged FAIL or IMPROVE and fix nothing themselves. Rounds are capped, and lessons go back into the tool.

    06

    No recommendations or tax calls.

    The tools make no recommendation. The two-pager's price target defaults to the Street-case value and says so; any other target is the user's choice. No tool makes a tax determination.

    FAQ

    Frequently asked questions.

    Did you write the code yourself?

    Not line by line. I built these tools with Claude, and my part is deciding what each one computes and how: the modelling conventions (SBC as a real cost, interest on opening balances, the multiple-selection rules), the checks a model has to pass, the report structure and the review panel. Then I run the tools on real companies, find what breaks, and change the tool so the next run does not repeat it.

    The editor at the top of this page shows excerpts of the plugin's files, and my GitHub profile has the public repositories.

    Is the workbook on this page the one the plugin builds?

    Yes. It is rebuilt from the plugin's Spotify input file with dcf_build.py and recalculated in LibreOffice for each of the four cases, so every value, formula and colour comes from that file. Two things differ from the file as shipped: the notes gain is entered net of FX (€154m), as its label and the build notes say, and the 52-week range on the Cover is blank because the price history file is not bundled.

    It reproduces the figures on this page: $515.03 Street, $601.83 management, $721.44 bull and $290.21 bear per share, $654.11 with the exit multiple, 1,984 formulas and zero errors.

    Where does the data come from?

    The diligence pack goes to SEC EDGAR and company investor-relations material first (filings, decks, transcripts), then yfinance, then secondary sources such as StockAnalysis and Trading Economics. Consensus figures in the Spotify model are Yahoo Finance's. The screener takes numbers from LSEG Refinitiv and yfinance and qualitative context from web search. The indexing tools use a connected market-data source or yfinance, and stop if neither is available.

    Figures are labelled with their basis, source and as-of date, and gaps are written down rather than filled in.

    How do you know the model is right?

    Three layers. The Checks tab tests the identities (balance sheet, cash, equity roll-forward, debt schedule, grid centre) and the plausibility ranges (terminal value share, implied exit multiple, EPS against consensus). The validator recalculates four scenarios and three toggles and asserts zero errors. Then the first forecast year is reconciled line by line and magnitudes are sense-checked, for example year-one unlevered FCF against the company's own reported FCF.

    On Spotify that loop caught a €154m balance-sheet break, a data field that was wrong by 2.5x and a fix applied to the wrong file.

    Why a reverse DCF instead of a normal one?

    Because a forecast of your own mostly tells you what you assumed. Starting from the price tells you what the market already believes, and the work becomes judging whether the evidence points above or below that. The tool still builds the full forward DCF; the reverse view sits on the same model and has to tie back to it.

    How did you make a run faster?

    A full run originally took about a day. I rebuilt it for speed by moving every numeric exhibit into scripts, giving each research agent a call budget, fixing the report skeleton, driving the DCF from one input file with one-command validation, and adding an express mode (three analysts, one reviewer) and a refresh mode that reuses the company's work folder and rebuilds only what new data touches.

    What are the limitations?

    Spotify is the only company the full pack has been run on so far, and the builder still carries Spotify-specific lines (the FY2026 to FY2035 columns, the notes rows, the share-count band, the Investor Day check, the litigation line and the Bund-based rate) that need adapting for the next company. Consensus is an aggregate, not a set of broker models, so the Street case replicates what consensus implies rather than any single analyst's view.

    In the Spotify model, peer multiples were trailing, the comps tab is a prototype, FX was not forecast and a share-price-linked payroll tax was assumed neutral. The direct indexing backtest uses today's constituents, so it carries survivorship bias, and it excludes trading costs and taxes. Sentiment scores and regime labels in the screener are model judgments and are marked as such.

    Can I ask questions about the tools?

    Use the chat (bottom right, or ⌘K or Ctrl K). It answers questions about these projects from what is on this page, says so when the page does not cover something, and declines unrelated questions. It runs on an NVIDIA-hosted model and is rate-limited. For anything else, email me.

    Where should I look if I only have two minutes?

    The Spotify figures near the top, then the model itself: switch the Cover to the Bear case and open the Checks tab. Those show what the tools produce and how much of the work goes into making sure it is right.

    The repositories are public on GitHub.
    The Spotify workbook is above.