finance-skills 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. finance_skills-0.3.0/LICENSE +21 -0
  2. finance_skills-0.3.0/PKG-INFO +443 -0
  3. finance_skills-0.3.0/README.md +423 -0
  4. finance_skills-0.3.0/finance_skills.egg-info/PKG-INFO +443 -0
  5. finance_skills-0.3.0/finance_skills.egg-info/SOURCES.txt +40 -0
  6. finance_skills-0.3.0/finance_skills.egg-info/dependency_links.txt +1 -0
  7. finance_skills-0.3.0/finance_skills.egg-info/entry_points.txt +2 -0
  8. finance_skills-0.3.0/finance_skills.egg-info/requires.txt +1 -0
  9. finance_skills-0.3.0/finance_skills.egg-info/top_level.txt +1 -0
  10. finance_skills-0.3.0/pyproject.toml +38 -0
  11. finance_skills-0.3.0/scripts/__init__.py +12 -0
  12. finance_skills-0.3.0/scripts/_entry.py +24 -0
  13. finance_skills-0.3.0/scripts/analyze.py +264 -0
  14. finance_skills-0.3.0/scripts/company.py +211 -0
  15. finance_skills-0.3.0/scripts/compare.py +144 -0
  16. finance_skills-0.3.0/scripts/data.py +284 -0
  17. finance_skills-0.3.0/scripts/export.py +123 -0
  18. finance_skills-0.3.0/scripts/framework.py +188 -0
  19. finance_skills-0.3.0/scripts/health.py +141 -0
  20. finance_skills-0.3.0/scripts/learn.py +172 -0
  21. finance_skills-0.3.0/scripts/metrics.py +324 -0
  22. finance_skills-0.3.0/scripts/redflags.py +135 -0
  23. finance_skills-0.3.0/scripts/router.py +311 -0
  24. finance_skills-0.3.0/scripts/screen.py +150 -0
  25. finance_skills-0.3.0/scripts/valuation.py +201 -0
  26. finance_skills-0.3.0/scripts/watchlist.py +158 -0
  27. finance_skills-0.3.0/setup.cfg +4 -0
  28. finance_skills-0.3.0/tests/test_analyze.py +81 -0
  29. finance_skills-0.3.0/tests/test_company.py +66 -0
  30. finance_skills-0.3.0/tests/test_compare.py +52 -0
  31. finance_skills-0.3.0/tests/test_data.py +67 -0
  32. finance_skills-0.3.0/tests/test_entry.py +51 -0
  33. finance_skills-0.3.0/tests/test_export.py +47 -0
  34. finance_skills-0.3.0/tests/test_framework.py +55 -0
  35. finance_skills-0.3.0/tests/test_health.py +56 -0
  36. finance_skills-0.3.0/tests/test_learn.py +37 -0
  37. finance_skills-0.3.0/tests/test_metrics.py +131 -0
  38. finance_skills-0.3.0/tests/test_redflags.py +63 -0
  39. finance_skills-0.3.0/tests/test_router.py +146 -0
  40. finance_skills-0.3.0/tests/test_screen.py +62 -0
  41. finance_skills-0.3.0/tests/test_valuation.py +58 -0
  42. finance_skills-0.3.0/tests/test_watchlist.py +72 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Bryan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,443 @@
1
+ Metadata-Version: 2.4
2
+ Name: finance-skills
3
+ Version: 0.3.0
4
+ Summary: Analyst-style equity research over one shared engine: segment-aware Rule of 40, DCF, red flags, screening — read-only, not investment advice.
5
+ Author: Bryan
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/notEhEnG/finance-skills
8
+ Project-URL: Repository, https://github.com/notEhEnG/finance-skills
9
+ Keywords: finance,stocks,equity-research,valuation,dcf,rule-of-40,fundamentals,yfinance
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Financial and Insurance Industry
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Topic :: Office/Business :: Financial :: Investment
14
+ Classifier: Operating System :: OS Independent
15
+ Requires-Python: >=3.9
16
+ Description-Content-Type: text/markdown
17
+ License-File: LICENSE
18
+ Requires-Dist: yfinance>=0.2
19
+ Dynamic: license-file
20
+
21
+ # finance-skills
22
+
23
+ Analyst-style equity research as an agent skill — driven by **real fundamentals**,
24
+ not narrated numbers. Ask about any public ticker in plain English and get a
25
+ report built from a fetch → compute pipeline.
26
+
27
+ > **Read-only. Not investment advice.** It only reads public market data, never
28
+ > places trades, and every figure should be verified against primary filings.
29
+
30
+ ```
31
+ /finance-skills analyze Do you think NBIS is a buy?
32
+ /finance-skills is NVDA overvalued?
33
+ /finance-skills compare AMD and NVDA
34
+ ```
35
+
36
+ ## What makes it different
37
+
38
+ Most "Rule of 40" tools compute one flat number. This one **classifies the
39
+ company's growth/capital regime first**, then picks the right formula and peer
40
+ benchmark — the mistake experienced analysts flag most often on names like
41
+ CoreWeave (CRWV) and Nebius (NBIS), whose GPU capex breaks the classic formula.
42
+ See [`references/rule40.md`](references/rule40.md).
43
+
44
+ ## Install as a skill (`/finance-skills`)
45
+
46
+ The whole repo installs as one skill for Claude Code, Antigravity, or a
47
+ Codex-compatible tool. Easiest — ask your agent:
48
+
49
+ ```text
50
+ Hey Claude, install this skill https://github.com/notEhEnG/finance-skills
51
+ ```
52
+
53
+ Or one command:
54
+
55
+ ```bash
56
+ curl -fsSL https://raw.githubusercontent.com/notEhEnG/finance-skills/main/install.sh | bash -s -- claude
57
+ # or: ... | bash -s -- antigravity (or codex, or all)
58
+ ```
59
+
60
+ Or manually copy the repo into the tool's skill dir (`scripts/` must sit next to
61
+ `SKILL.md` so the engine can run):
62
+
63
+ | Tool | Install path | Invoke |
64
+ |---|---|---|
65
+ | Claude Code | `.claude/skills/finance-skills/SKILL.md` | `/finance-skills analyze Do you think NBIS is a buy?` |
66
+ | Antigravity IDE | `.antigravity/skills/finance-skills/SKILL.md` | `/finance-skills is NVDA a buy?` or assign to an agent |
67
+ | Codex-compatible | `<codex-skill-dir>/finance-skills/SKILL.md` | `/finance-skills ...` |
68
+
69
+ Then, if needed: `pip install yfinance`.
70
+
71
+ ## How invocation works
72
+
73
+ `/finance-skills [verb] <plain-English question>`. The skill (1) extracts the
74
+ ticker (mapping company names, e.g. Nebius → NBIS), (2) determines intent (an
75
+ explicit verb or inferred from the question), (3) runs the engine and answers
76
+ the actual question with cited numbers. So all of these are equivalent:
77
+
78
+ ```
79
+ /finance-skills is NBIS a buy?
80
+ /finance-skills analyze Do you think NBIS is a buy?
81
+ /finance-skills analyze NBIS
82
+ ```
83
+
84
+ ### Keyword routing (plain English → verb)
85
+
86
+ Step 2 isn't a guess. The router carries an explicit **keyword map**: trigger
87
+ phrases resolve a plain-English question to a verb deterministically (the
88
+ **longest matching phrase wins**, so `"is it a buy"` beats a bare `"buy"`). Only
89
+ the top verbs are keyworded; anything else still resolves from an explicit verb
90
+ token or the semantic routing table.
91
+
92
+ ```bash
93
+ python3 scripts/router.py route "is NBIS a value trap?" # -> risk
94
+ python3 scripts/router.py route "any red flags in PLTR?" # -> redflags
95
+ python3 scripts/router.py route "how does AMD compare to NVDA" # -> compare
96
+ ```
97
+
98
+ | If the question sounds like… | Trigger phrases (examples) | Routes to |
99
+ |---|---|---|
100
+ | is it cheap / a buy | `is it a buy`, `overvalued`, `undervalued`, `fair value`, `should i buy`, `cheap` | `valuation` |
101
+ | is it safe | `is it safe`, `value trap`, `blow up`, `go bankrupt`, `too much debt`, `risky` | `risk` |
102
+ | anything wrong | `red flag(s)`, `warning sign`, `going concern`, `anything to worry` | `redflags` |
103
+ | can it survive | `financial health`, `balance sheet`, `cash runway`, `solvency`, `self-funding` | `health` |
104
+ | is it growing | `growth rate`, `top line`, `is it growing`, `decelerating`, `accelerating` | `growth` |
105
+ | does it have an edge | `a moat`, `competitive advantage`, `pricing power`, `defensible` | `moat` |
106
+ | what's it worth | `intrinsic value`, `discounted cash flow`, `fair price`, `dcf`, `worth` | `dcf` |
107
+ | is growth efficient | `rule of 40`, `rule40`, `r40` | `rule40` |
108
+ | which is better | `compare`, `versus`, `vs`, `head-to-head`, `better than` | `compare` |
109
+ | tell me everything | `tell me about`, `walk me through`, `full picture`, `deep dive` | `company` |
110
+
111
+ `route` returns nothing when no phrase matches (then the agent falls back to the
112
+ semantic routing table); a leading question word like *what*/*how* never hijacks
113
+ routing. The map lives in `KEYWORDS` in [`scripts/router.py`](scripts/router.py).
114
+
115
+ ## Slash commands
116
+
117
+ Plain English always works (Layer 1). But the **verbs are the primary interface** —
118
+ a polished CLI over one shared engine, so numbers never diverge across commands.
119
+
120
+ | Command | Answers | Backed by |
121
+ |---|---|---|
122
+ | `/finance-skills <question>` | anything — routes to the right lens | `analyze` + intent routing |
123
+ | `/finance-skills company <ticker>` | "tell me about this company" — a guided walkthrough | `scripts/company.py` |
124
+ | `/finance-skills analyze <ticker>` | "should I invest?" end-to-end (flagship) | `scripts/analyze.py` |
125
+ | `/finance-skills framework <name> <ticker>` | "run the SaaS / neocloud / semis lens" | `scripts/framework.py` |
126
+ | `/finance-skills valuation <ticker>` | "is it cheap?" | DCF + EV/EBITDA + Rule 40 |
127
+ | `/finance-skills dcf <ticker>` | "what's it worth?" | DCF slice of `analyze` |
128
+ | `/finance-skills rule40 <ticker>` | "is growth efficient?" | segment-aware Rule of 40 |
129
+ | `/finance-skills growth <ticker>` | "is it growing?" | growth + margins + regime |
130
+ | `/finance-skills risk <ticker>` | "what could go wrong?" | leverage, FCF, dilution, capex gap |
131
+ | `/finance-skills redflags <ticker>` | "any warning signs?" | `scripts/redflags.py` (severity-ranked flags) |
132
+ | `/finance-skills health <ticker>` | "can it survive?" | `scripts/health.py` (leverage, runway, dilution) |
133
+ | `/finance-skills moat <ticker>` | "does it have a durable edge?" | margins vs peers + `references/` |
134
+ | `/finance-skills fiveforces <ticker>` | "how good is the industry structure?" | Porter, applied to engine evidence |
135
+ | `/finance-skills compare <a> <b> [...]` | "which is better?" | `scripts/compare.py` (side-by-side table) |
136
+ | `/finance-skills screen "<rule>" [tickers]` | "which pass this filter?" | `scripts/screen.py` (`field op value`) |
137
+ | `/finance-skills watchlist add\|list\|run <verb>` | "track a set, run any verb across it" | `scripts/watchlist.py` |
138
+ | `/finance-skills export <ticker> --format md\|json\|csv` | "give me a shareable file" | `scripts/export.py` |
139
+ | `/finance-skills learn <concept>` | "what *is* a Magic Number / DCF / NRR?" | `scripts/learn.py` (offline) |
140
+ | `/finance-skills help` | grouped command help | `scripts/router.py help` |
141
+
142
+ Shorthand and typos resolve instead of erroring (`co`→company, `fw`→framework,
143
+ `val`→valuation, `r40`→rule40, `5forces`→fiveforces, `vluation`→valuation).
144
+
145
+ ### `company` — example output (the guided walkthrough)
146
+
147
+ `/finance-skills company CRWV` steps through the business top-to-bottom, each
148
+ stage flowing into the next, and ends with a synthesised verdict:
149
+
150
+ **At a glance:** the 9 stages for CRWV — strong margins (gross **70%**) but
151
+ **BELOW** its Rule-of-40 bar, negative FCF, and a verdict that hinges on
152
+ **backlog & funding runway**.
153
+
154
+ ```text
155
+ ═══ CoreWeave, Inc. (CRWV) — company walkthrough ═══
156
+ Source: fixture · as of 2026-Q1 [SAMPLE DATA — not live]
157
+ Price: $100 Market cap: $48.00B
158
+
159
+ ■ Business Model
160
+ Sector: Technology / Information Technology Services
161
+ AI neocloud/hyperscaler — extreme growth funded by heavy GPU capex; judged on cash burn and backlog, not headline EBITDA.
162
+
163
+ ■ Competitive Advantage
164
+ Gross margin 70.0% — high; suggests pricing power or a software-like cost structure.
165
+ EBITDA margin 56.0% — operating leverage already showing.
166
+
167
+ ■ Revenue Drivers
168
+ Revenue: $1.90B
169
+ Growth (YoY): 111.1%.
170
+
171
+ ■ Margins
172
+ Gross: 70.0% EBITDA: 56.0% FCF: -315.8%
173
+ Negative free cash flow — growth is consuming cash (normal for the regime, watch runway).
174
+
175
+ ■ Financial Health
176
+ Net debt: $11.50B
177
+ Net debt / EBITDA: 10.81x — elevated; watch refinancing and covenants.
178
+
179
+ ■ Growth
180
+ Growth rate: 111.1%
181
+ AI neocloud/hyperscaler regime.
182
+
183
+ ■ Valuation
184
+ DCF: DCF skipped: free cash flow is not positive (typical for capex-heavy growth names).
185
+ EV/EBITDA: 55.9x.
186
+
187
+ ■ Risks
188
+ Capital-intensity gap 372 pts — growth is capex-funded, not organically profitable.
189
+ Below its Rule-of-40 bar (judged -668 vs 38).
190
+ Share dilution 9.1% YoY — growth partly 'bought' with equity.
191
+ Cash burn — depends on continued access to funding.
192
+
193
+ ■ Final Verdict
194
+ A capital-intensive neocloud: the story is backlog and funding runway, not this quarter's margin.
195
+ Falls short of its Rule-of-40 bar today.
196
+ No DCF (FCF not positive), so lean on Rule-of-40 and multiples instead of intrinsic value.
197
+ Not a recommendation — verify against primary filings before acting.
198
+ ```
199
+
200
+ ### `valuation` — "is it cheap?" as a table
201
+
202
+ `/finance-skills valuation <ticker>` lays the valuation slice out as a scannable
203
+ **Metric | Value | Read** table (DCF, EV/Sales, EV/EBITDA, Rule 40), flagging a
204
+ distorted EV/EBITDA when EBITDA margin exceeds 100%:
205
+
206
+ ```text
207
+ ═══ CoreWeave, Inc. (CRWV) — valuation ═══
208
+ Source: fixture · as of 2026-Q1 [SAMPLE DATA — not live]
209
+
210
+ Metric Value Read
211
+ ───────────────────────────────────────────────────────────────────
212
+ Price $100 —
213
+ Market cap $48.00B —
214
+ Enterprise value $59.50B market cap + net debt
215
+ EV / Sales 31.3x extreme — priced on growth, not sales
216
+ EV / EBITDA 55.9x expensive
217
+ DCF / share n/a FCF negative — DCF skipped
218
+ Rule of 40 -668 vs 38 BELOW BAR (ai neocloud)
219
+ Revenue growth 111.1% hypergrowth
220
+ FCF margin -315.8% cash burn — depends on funding
221
+ Net debt / EBITDA 10.81x elevated — watch refinancing
222
+
223
+ Verdict: No DCF (FCF not positive), so it can't be anchored to intrinsic value — expensive on EV/Sales 31.3x; a growth/backlog bet, not supported by current cash flows.
224
+ ```
225
+
226
+ ### `framework` — run a whole lens at once (honest about data)
227
+
228
+ `/finance-skills framework saas CRWV` runs every SaaS metric instead of making
229
+ you pick. Metrics that need a **disclosed KPI not in the financial statements**
230
+ (Magic Number, CAC payback, NRR) are flagged with their definition — never faked:
231
+
232
+ **At a glance:** computed from filings — Rule of 40 **BELOW BAR**, gross margin
233
+ **70.0%**, EV/EBITDA **55.9x**; Magic Number, CAC payback & NRR flagged
234
+ _**needs disclosed KPI**_ rather than fabricated.
235
+
236
+ ```text
237
+ ═══ CoreWeave, Inc. (CRWV) — SaaS / software quality framework ═══
238
+ Source: fixture · as of 2026-Q1 [SAMPLE DATA — not live]
239
+
240
+ Metric Value / status
241
+ ───────────────────────────────────────────────────────────────────
242
+ Rule of 40 judged -668 vs 38 bar → BELOW BAR (EBITDA 167 / FCF -205, gap 372)
243
+ Gross margin 70.0%
244
+ FCF margin -315.8%
245
+ Revenue growth (YoY) 111.1%
246
+ EV/EBITDA 55.9x
247
+ Magic Number ⚠ needs disclosed KPI
248
+ CAC payback ⚠ needs disclosed KPI
249
+ Net revenue retention (NRR) ⚠ needs disclosed KPI
250
+
251
+ Not in the financial statements — check the 10-K / investor deck (defined, not faked):
252
+ • Magic Number — net-new ARR ÷ prior-quarter S&M spend; >0.75 = efficient growth. Needs S&M + ARR disclosure.
253
+ • CAC payback — months of gross-margin-adjusted revenue to recover customer acquisition cost. Needs S&M + new-customer/ARR disclosure.
254
+ • Net revenue retention (NRR) — expansion − churn on existing customers; >120% is elite. A disclosed KPI, not in the financial statements.
255
+ ```
256
+
257
+ Frameworks: `saas`, `neocloud`, `semiconductor` (`python3 scripts/framework.py list`).
258
+
259
+ ### `learn` — teach the concept, no ticker needed
260
+
261
+ `/finance-skills learn dcf` (also `rule40`, `magic-number`, `nrr`, `five-forces`, …):
262
+
263
+ ```text
264
+ ═══ dcf ═══
265
+ Discounted cash flow: a company is worth the present value of its future free cash flow.
266
+
267
+ How to compute / read it:
268
+ Two-stage model: grow FCF for N years, discount each year back, add a Gordon terminal value, subtract net debt, divide by shares. Here growth is a heuristic (trailing revenue growth, capped), discount 10%, terminal 3%.
269
+
270
+ Common trap:
271
+ Output is only as good as the assumptions — tiny changes in growth/discount swing it wildly. Treat it as a rough anchor, and note it's skipped when FCF is negative.
272
+ ```
273
+
274
+ ### `analyze` — example output
275
+
276
+ `/finance-skills analyze CRWV` (shown on the offline sample via `--fixture`;
277
+ live output has the same shape with a yfinance source + timestamp):
278
+
279
+ **At a glance:** CRWV — AI-neocloud regime · Rule of 40 **BELOW BAR** (-668 vs
280
+ 38) · burning cash (FCF **-315.8%**) · leverage **10.81x**.
281
+
282
+ ```text
283
+ ═══ CoreWeave, Inc. (CRWV) ═══
284
+ Source: fixture · as of 2026-Q1 [SAMPLE DATA — not live]
285
+ Sector: Technology / Information Technology Services
286
+ Price: $100 Market cap: $48.00B
287
+
288
+ Fundamentals (derived):
289
+ Revenue growth (YoY): 111.1%
290
+ EBITDA margin: 56.0% FCF margin: -315.8%
291
+ Capex intensity: 463.2% Share dilution: 9.1%
292
+ Net debt: $11.50B
293
+
294
+ Rule of 40 — regime: ai neocloud
295
+ EBITDA-based: 167 FCF-based: -205 capital-intensity gap: 372
296
+ Capex-adjusted: -668 dilution-adjusted: -677
297
+ Judged on -668 vs benchmark 38 → BELOW BAR
298
+ Verdict: Capital-intensive: growth is burning cash faster than it earns; watch backlog/RPO and funding runway.
299
+ • Neocloud regime: the EBITDA-based score overstates health; judging on the capex-adjusted FCF score to reflect real GPU capital burn.
300
+ • Large capital-intensity gap (372 pts) — growth is capex-funded, not organically profitable.
301
+
302
+ DCF: DCF skipped: free cash flow is not positive (typical for capex-heavy growth names).
303
+ Leverage: net debt / EBITDA = 10.81x
304
+
305
+ ────────────────────────────────────────────────────────────
306
+ Read-only market analysis for research/education. Not investment advice; no trades are placed. Verify figures against primary filings before acting.
307
+ ```
308
+
309
+ The `valuation`, `growth`, `risk`, and `moat` verbs run the same engine and lead
310
+ with the matching slice of that report (e.g. `risk` leads with leverage 10.81×,
311
+ the 372-pt capital-intensity gap, and dilution).
312
+
313
+ ### `help` — example output
314
+
315
+ `/finance-skills help`:
316
+
317
+ ```text
318
+ finance-skills — ask in plain English, or use a verb.
319
+
320
+ Top verbs: company analyze valuation framework compare learn
321
+
322
+ By question:
323
+ Whole company → company, analyze, framework
324
+ Is it cheap? → valuation, dcf, rule40, benchmark
325
+ Is it safe? → risk, redflags, health
326
+ Will it grow? → growth, opportunities, earnings
327
+ Does it have an edge? → moat, fiveforces, management
328
+ How does it compare? → compare, competitors, industry
329
+ Learn a concept → learn
330
+ Sector-specific → semiconductor, ai-cloud, banking, reit, insurance
331
+ Power tools → screen, rank, portfolio, watchlist, export
332
+
333
+ Shorthand works too: val→valuation, r40→rule40, comp→compare, semis→semiconductor.
334
+ Typos are tolerated (e.g. 'vluation' → valuation).
335
+ ```
336
+
337
+ ### Natural-language front door — example
338
+
339
+ `/finance-skills Do you think NBIS and CRWV is a buy?` first extracts the tickers,
340
+ then runs the engine per ticker:
341
+
342
+ ```text
343
+ $ python3 scripts/router.py tickers "Do you think NBIS and CRWV is a buy?"
344
+ NBIS CRWV
345
+ $ python3 scripts/router.py r40
346
+ r40 → rule40 (alias)
347
+ ```
348
+
349
+ ## Architecture
350
+
351
+ ```
352
+ finance-skills/
353
+ ├── SKILL.md # skill entry: triggers, safety, invocation contract
354
+ ├── install.sh # install as an agent skill (claude/antigravity/codex)
355
+ ├── pyproject.toml # PEP 621 packaging (installs scripts/ as `finance_skills`)
356
+ ├── scripts/ # sources — also the importable `finance_skills` package
357
+ │ ├── __init__.py # package marker + __version__
358
+ │ ├── _entry.py # console entry: `finance-skills` -> router.main(argv)
359
+ │ ├── data.py # yfinance fetch + normalise + 6h cache + graceful fallback
360
+ │ ├── metrics.py # PURE engine: segment-aware Rule 40, DCF, EV/EBITDA, Altman Z, Piotroski
361
+ │ ├── analyze.py # orchestrator: fetch → compute → report (flagship `analyze`)
362
+ │ ├── company.py # 9-stage sequential walkthrough (view over analyze)
363
+ │ ├── framework.py # named frameworks as checklists (saas/neocloud/semiconductor)
364
+ │ ├── redflags.py # warning-sign scan with severity (view over analyze)
365
+ │ ├── health.py # solvency: leverage, cash runway, dilution (view over analyze)
366
+ │ ├── compare.py # side-by-side table for two+ tickers
367
+ │ ├── screen.py # filter a set of tickers by a tiny `field op value` rule
368
+ │ ├── watchlist.py # saved named ticker lists; run any verb across them
369
+ │ ├── export.py # render a verb to a Markdown / JSON / CSV file
370
+ │ ├── learn.py # offline concept explainers (no ticker, no network)
371
+ │ └── router.py # ticker extraction + alias/fuzzy + keyword→verb routing (pure)
372
+ ├── references/
373
+ │ ├── rule40.md # segment-aware Rule of 40 methodology + benchmarks
374
+ │ └── ai-cloud.md # AI-cloud/neocloud sector framework (capex, backlog/RPO)
375
+ ├── tests/ # offline unit tests (pure math + orchestrator + router + CLI)
376
+ └── requirements.txt # yfinance
377
+ ```
378
+
379
+ The same files serve two roles. Run in place, `python3 scripts/<mod>.py` drives
380
+ the agent skill (what SKILL.md / install.sh use). Installed from PyPI, the
381
+ directory is remapped to the importable **`finance_skills`** package with a
382
+ `finance-skills` console command — the intra-module imports resolve both ways via
383
+ a small `try: from finance_skills import … / except ImportError: import …` shim.
384
+
385
+ The **engine is one source of truth**: `metrics.py` is pure and offline-testable;
386
+ `data.py` is the only module that touches the network; `analyze.py` composes them.
387
+ Every specialised command (company, framework, valuation, dcf, rule40, risk…) is
388
+ a *view* over `analyze`, so numbers never diverge between commands.
389
+
390
+ ## Install as a Python package
391
+
392
+ ```bash
393
+ pip install finance-skills # console command + importable engine
394
+ finance-skills help # grouped command help
395
+ python -c "import finance_skills" # the engine as a library
396
+ ```
397
+
398
+ ## CLI usage (also drives the skill)
399
+
400
+ ```bash
401
+ pip install -r requirements.txt
402
+
403
+ python3 scripts/analyze.py NVDA # full live report
404
+ python3 scripts/company.py NVDA # guided 9-stage walkthrough
405
+ python3 scripts/framework.py saas NVDA # run the SaaS lens as a checklist
406
+ python3 scripts/learn.py rule40 # explain a concept (offline)
407
+ python3 scripts/analyze.py CRWV --fixture # offline sample (no network)
408
+ python3 scripts/router.py tickers "is NBIS a buy?" # -> NBIS
409
+ python3 scripts/router.py help # grouped help
410
+ ```
411
+
412
+ ## Platform note
413
+
414
+ Live fetching uses `yfinance` (network) → works on **Claude Code** and locally,
415
+ **not** on the Claude.ai sandbox. Without network, use `--fixture` (CRWV, NBIS
416
+ samples, clearly labelled non-live) or the skill will say live data is unavailable.
417
+
418
+ ## Development
419
+
420
+ ```bash
421
+ python3 -m pytest tests/ -q # 118 offline tests (no network needed)
422
+ ```
423
+
424
+ - `tests/test_metrics.py` — regime classification, dual-margin/capex-adjusted
425
+ Rule 40 (locks the CoreWeave/Nebius examples), DCF guards, Altman Z, Piotroski.
426
+ - `tests/test_analyze.py` — orchestrator on fixtures + graceful no-data path.
427
+ - `tests/test_data.py` — statement column-ordering + net-debt fail-closed behaviour.
428
+ - `tests/test_company.py` — the 9 walkthrough stages, in order, with data-gap flags.
429
+ - `tests/test_framework.py` — computed metrics vs honestly-flagged disclosed KPIs.
430
+ - `tests/test_learn.py` — concept/alias/fuzzy resolution for the explainers.
431
+ - `tests/test_router.py` — ticker extraction, alias/fuzzy + keyword→verb routing, grouped help.
432
+ - `tests/test_redflags.py` / `test_health.py` / `test_compare.py` — the new engine views.
433
+ - `tests/test_screen.py` — the safe `field op value` rule parser and fail-closed missing data.
434
+ - `tests/test_watchlist.py` / `test_export.py` — persistence and md/json/csv output.
435
+ - `tests/test_entry.py` — the `finance-skills` console entry point runs `help`.
436
+
437
+ ## Status & roadmap
438
+
439
+ The real engine proven end-to-end on live data plus offline fixtures, installable
440
+ as a cross-tool skill, with a **verb-first CLI** (`company`, `framework`, `learn`,
441
+ …) layered over it. Next, over the same engine: more sector references
442
+ (`semiconductor.md`, `banking.md`, `reit.md`), `screen`/`rank` views, trend
443
+ arrows, and backlog/RPO ingestion to light up the framework KPI rows.