Skip to content

Commit 7367bb3

Browse files
committed
Add investment memo skill
1 parent 90b802c commit 7367bb3

5 files changed

Lines changed: 800 additions & 1 deletion

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "dexter-ts",
3-
"version": "2026.5.20",
3+
"version": "2026.5.24",
44
"description": "Dexter - AI agent for deep financial research.",
55
"type": "module",
66
"main": "src/index.tsx",

src/skills/write-memo/SKILL.md

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
---
2+
name: write-memo
3+
description: Drafts a professional investment memo (HTML output) for a long or short equity idea, structured the way a hedge fund analyst would present a thesis to a PM. Triggers when the user asks to "write a memo", "draft an investment memo", "write up a thesis", "pitch this stock", "memo on [ticker]", "long writeup", "short writeup", or similar. Produces a 1-page HTML file at .dexter/memos/.
4+
---
5+
6+
# Write Investment Memo Skill
7+
8+
Produces a buyside-quality investment memo as a self-contained HTML file. The memo is opinionated and falsifiable — it leads with a variant view and steelmans the bear case. The output is the deliverable; the chat response is just a header summary plus the file path.
9+
10+
## Workflow Checklist
11+
12+
Copy and track progress:
13+
```
14+
Investment Memo Progress:
15+
- [ ] Step 1: Frame the trade (direction, horizon, variant view)
16+
- [ ] Step 2: Gather data (financials, market, filings)
17+
- [ ] Step 3: Build Bear / Base / Bull scenarios
18+
- [ ] Step 4: Optional DCF anchor for base case
19+
- [ ] Step 5: Draft memo content (fill all slots)
20+
- [ ] Step 6: Self-critique pass
21+
- [ ] Step 7: Render HTML to .dexter/memos/
22+
- [ ] Step 8: Report header summary + file path
23+
```
24+
25+
## Step 1: Frame the Trade
26+
27+
Confirm or ask for the following before drafting:
28+
29+
- **Ticker** (required)
30+
- **Direction**: long or short (required)
31+
- **Horizon**: 3mo / 6mo / 12mo / 2yr+ (default 12mo if not specified)
32+
- **Conviction**: high / medium / low (default medium)
33+
- **Variant view**: one sentence — what the analyst sees that consensus doesn't
34+
35+
**If the user does not provide a variant view**: do not ask repeatedly. Gather data in Step 2 first, then derive a candidate variant view from where your model meaningfully diverges from consensus (e.g., "our '27 EPS is $X vs consensus $Y because [driver]"). Present it as a draft and let the analyst accept, refine, or replace before you proceed to Step 5.
36+
37+
## Step 2: Gather Data (Parallel)
38+
39+
Issue these tool calls in parallel:
40+
41+
### 2.1 Financials
42+
Call `get_financials`:
43+
- `"[TICKER] annual income statements last 5 years"` — revenue, operating income, net income, EPS, margins
44+
- `"[TICKER] annual cash flow statements last 5 years"` — operating CF, capex, FCF
45+
- `"[TICKER] latest balance sheet"` — debt, cash, shares outstanding
46+
- `"[TICKER] financial metrics snapshot"` — P/E, EV, ROIC, FCF growth, debt/equity, margins
47+
- `"[TICKER] segmented financials"` — segment revenue, segment margins (if multi-segment)
48+
- `"[TICKER] earnings history last 8 quarters"` — beats/misses, surprises
49+
- `"[TICKER] company facts"` — sector, industry, market cap
50+
- `"[TICKER] KPI guidance"` and `"[TICKER] KPI metrics"` — management-provided KPIs and guidance
51+
52+
### 2.2 Market & Ownership
53+
Call `get_market_data`:
54+
- `"[TICKER] price snapshot"` — current price, 52-week range, market cap
55+
- `"[TICKER] historical prices last 12 months"` — for return / multiple compression context
56+
- `"[TICKER] insider trades last 6 months"` — recent buys/sells, dollar amounts
57+
- `"[TICKER] institutional holdings"` — top holders, recent additions / reductions
58+
- `"[TICKER] news last 30 days"` — recent material events
59+
60+
### 2.3 Filings
61+
Call `read_filings`:
62+
- Most recent 10-K Item 1 (Business) — for business snapshot language
63+
- Most recent 10-K Item 1A (Risk Factors) — to source risks from the company itself
64+
- Most recent 10-Q — recent quarterly trajectory
65+
66+
### 2.4 Memory (optional)
67+
Call `memory_search` with the ticker — surfaces any prior notes, prior memos, or user-provided constraints (e.g., risk tolerance, sector exposure already in book).
68+
69+
### 2.5 Sentiment (optional, only if time-sensitive)
70+
Call `x_search` for recent material chatter on the ticker. Skip if the thesis is fundamental and not catalyst-driven this week.
71+
72+
## Step 3: Build Scenarios
73+
74+
Construct Bear / Base / Bull scenarios. Each scenario is **driver-based**, not a single number pulled from the air.
75+
76+
For each scenario specify:
77+
- **Revenue growth** (forecast year, 2-3 years out)
78+
- **EBIT / operating margin** at that point
79+
- **Exit multiple** (P/E, EV/EBITDA, or EV/Sales as appropriate for the sector)
80+
- **Probability weight** (the three must sum to 100%)
81+
- **Price target** (derived from the above)
82+
- **Return** vs. current price (with sign)
83+
84+
Then compute:
85+
- **Probability-weighted return** = sum(prob × return) across scenarios
86+
- **Upside / downside ratio** = |bull return| / |bear return|
87+
88+
**Asymmetry check**: if upside/downside < 2x, flag this prominently. A weak-asymmetry setup is a coin flip, not a trade. Either revise the scenarios honestly, or note the weak asymmetry in the memo (do not hide it).
89+
90+
## Step 4: Optional DCF Anchor
91+
92+
For base case, optionally invoke the `dcf-valuation` skill via the `skill` tool to produce an intrinsic value anchor. Use it as a cross-check against your base-case price target, not as a replacement.
93+
94+
## Step 5: Draft Memo Content
95+
96+
Read the template and style guide:
97+
- [memo-template.html](memo-template.html)
98+
- [memo-style.md](memo-style.md)
99+
- [examples.md](examples.md) — pattern-match tone and density
100+
101+
Fill every slot. Slots are listed in the template — do not skip any. Slot-specific guidance:
102+
103+
### `{{variant_view}}`
104+
Three sentences max. Lead with the divergence from consensus: *what we see, why we think it, why the market hasn't priced it*. If the user did not provide one, this is where your derived candidate goes.
105+
106+
### `{{thesis_bullets}}`
107+
3-5 bullets, each in this format:
108+
> **[Claim]**[Evidence with a specific number]. *Wrong if [observable falsifier].*
109+
110+
Example:
111+
> **Ad-tier reaches 15% of subs by '27** — Q1 disclosed 40M ad-tier subs (+85% YoY) on a 270M base; trajectory implies 15% mix at constant adds. *Wrong if ad-tier ARPU compresses below $8 due to inventory glut.*
112+
113+
Each bullet must be **falsifiable**. No "great management", "strong moat", "wide TAM" without a specific operational metric behind it.
114+
115+
### `{{business_snapshot}}`
116+
4-5 lines max. What they sell, how they make money, segment mix, unit economics that matter for the thesis. **No founding-year boilerplate.** Pull verbatim from the 10-K Item 1 where it tightens the language.
117+
118+
### `{{whats_priced_in}}`
119+
Current multiple, implied growth or margin assumption embedded in that multiple, sellside consensus numbers (revenue, EPS for FY+1 and FY+2). Then one sentence on where your model diverges and by how much.
120+
121+
### `{{scenario_table}}`
122+
Render as an HTML table. Columns: Bear / Base / Bull. Rows: Probability, Revenue growth (FY27), EBIT margin (FY27), Exit multiple, Price target, Return. Color returns: positive `class="pos"`, negative `class="neg"`.
123+
124+
### `{{bull_narrative}}`, `{{base_narrative}}`, `{{bear_narrative}}`
125+
One paragraph each (3-5 sentences). Each is a *coherent world*, not a list of factors:
126+
- **Bull**: what has to be true. Specific operational wins that compound. Tied to evidence we'd see in quarterly data.
127+
- **Base**: the thesis playing out as written.
128+
- **Bear**: steelmanned — written as if you believed it. Specific competitive losses, customer concentration risk materializing, multiple compression to a lower peer group. **If the bear paragraph reads weaker than the bull paragraph, rewrite it.**
129+
130+
### `{{catalysts_table}}`
131+
Table with columns: Event, Date / Quarter, Expected Impact. 3-5 entries. Dates should be specific (Q3 '26, Aug '26 earnings, Investor Day Nov '26).
132+
133+
### `{{risks_table}}`
134+
Table with columns: Risk, Mitigant, Tripwire. The tripwire is the **observable data point that would invalidate the thesis** (e.g., "Q3 ad-tier ARPU prints below $8", "top customer renewal pushed past Q4"). Tripwires distinguish a hedge fund memo from a sellside report.
135+
136+
### `{{position_management}}`
137+
Three short lines: suggested sizing (% NAV) anchored to conviction × asymmetry; entry price (current or limit); stop level or scale-out trigger.
138+
139+
### `{{monitoring_kpis}}`
140+
3-5 KPIs to track quarterly. These are the metrics that confirm or kill the thesis — not generic ones (revenue growth, EPS) but specific ones tied to your variant view.
141+
142+
## Step 6: Self-Critique Pass (Mandatory)
143+
144+
Before rendering, verify every check. If any fail, revise the relevant section before continuing.
145+
146+
1. **Variant view is actually variant.** Not a restatement of consensus dressed up as a view. The test: can you point to specific sellside notes / consensus numbers your view contradicts?
147+
2. **Every thesis bullet is falsifiable.** Each has a "wrong if" clause naming a specific observable.
148+
3. **Numbers behind every adjective.** No "strong growth" without the bps / %. No "expanding margins" without the basis point delta.
149+
4. **Bear case is steelmanned.** Read the bear paragraph aloud. If it reads weaker than the bull, rewrite.
150+
5. **Asymmetry ≥ 2x.** If not, the memo flags this in the header rather than hiding it.
151+
6. **Probability weights sum to 100%.**
152+
7. **Tripwires are observable.** Each risk has a data point an analyst could watch for, not a vibe.
153+
154+
## Step 7: Render HTML
155+
156+
1. Read `memo-template.html` via `read_file`
157+
2. Replace every `{{slot}}` placeholder with the content you drafted
158+
3. Set `{{date}}` to today's date in YYYY-MM-DD format
159+
4. Set `{{analyst}}` from memory if known, otherwise blank
160+
5. Write to `.dexter/memos/[TICKER]_[DIRECTION]_[YYYY-MM-DD].html` via `write_file`
161+
- Direction is `LONG` or `SHORT` (uppercase)
162+
- Example: `.dexter/memos/NFLX_LONG_2026-05-24.html`
163+
6. **Only** write a `.md` source file if the user explicitly requested one
164+
165+
The path uses forward slashes. The `write_file` tool will create the `.dexter/memos/` directory if it does not exist.
166+
167+
## Step 8: Report to Chat
168+
169+
Final chat response should be exactly this format and nothing more:
170+
171+
```
172+
[TICKER] · [LONG/SHORT] · Target $X (+Y% / -Y%) · Asymmetry [N.Nx] · [Conviction]
173+
174+
Memo saved to .dexter/memos/[FILENAME].html
175+
Open with: open .dexter/memos/[FILENAME].html
176+
```
177+
178+
Do not paste the full memo content into the chat. The file is the deliverable. The chat output is a scannable header.
179+
180+
## Critical Don'ts
181+
182+
- Do not paste the full memo as a chat response in addition to writing the file
183+
- Do not write a `.md` file alongside unless explicitly requested
184+
- Do not include charts, sparklines, scenario bars, or any visual element beyond tables
185+
- Do not add emoji anywhere — not in the memo, not in the chat response
186+
- Do not include a prominent "AI-generated" footer or branding
187+
- Do not skip the self-critique pass in Step 6
188+
- Do not invent consensus numbers — if you do not have them from a tool call, say so in the memo

src/skills/write-memo/examples.md

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
# Example Memo (for tone calibration)
2+
3+
This is a worked example for `NFLX LONG · 12mo`. Use it to pattern-match tone, density, and structure when drafting. **Do not copy the numbers** — fetch fresh data via the tools for any actual memo.
4+
5+
The example is shown as the content that would fill the template slots, not the final HTML.
6+
7+
---
8+
9+
**Header strip values**
10+
- Ticker: NFLX
11+
- Company: Netflix, Inc.
12+
- Direction: LONG
13+
- Conviction: HIGH
14+
- Horizon: 12mo
15+
- Current price: $620
16+
- Base target: $785
17+
- Upside: +27%
18+
- Asymmetry: 2.4x
19+
- Prob-weighted return: +18%
20+
21+
---
22+
23+
**`{{variant_view}}`**
24+
25+
Consensus models ad-tier as a single-digit revenue line for the next three years. We think it is a 20%+ contributor to '27 revenue and the primary multiple-rerate catalyst. The Street is anchored to subscription-only unit economics and has not updated for ad-tier ARPU running 30% above their first-year assumption.
26+
27+
---
28+
29+
**`{{thesis_bullets}}`** (HTML list items)
30+
31+
- **Ad-tier reaches 18% of subs by '27** — Q1 disclosed 40M ad-tier subs (+85% YoY) on a 270M base; at current adds and a 65% mix of new signups going to the ad tier, we model 51M ad-tier subs by end-'27. *Wrong if ad-tier mix of new signups falls below 50% for two consecutive quarters.*
32+
- **Ad-tier ARPU sustains $9+** — current ad CPMs of $35-45 imply $9-11 ARPU at 5 ad-min/hr inventory; management called out upfront commitments doubling YoY. *Wrong if disclosed ad ARPU prints below $8 in any quarterly disclosure.*
33+
- **Operating margin expands 600bps to 28% by '27** — content amortization peaks in '25 per management; incremental ad revenue is 70%+ margin. *Wrong if content spend grows above $20B in any year.*
34+
- **Multiple rerates from 28x to 35x as ad revenue mix exceeds 15%** — comparable transition (Spotify ad-tier, Roku) saw 25-40% multiple expansion when ad revenue crossed 15% of total. *Wrong if ad revenue stalls below 12% of total through '27.*
35+
36+
---
37+
38+
**`{{business_snapshot}}`**
39+
40+
Netflix is a global subscription video streaming service with 270M paid memberships across 190+ countries. The company licenses and produces original content; "we have one of the largest libraries of TV series and films, with content available in over 30 languages" (10-K Item 1). Two membership tiers contribute differently: standard and premium subscriptions (~$15-23/mo) drive 92% of revenue today; the ad-supported tier (~$7/mo plus advertising) launched late '22 and is now the company's stated highest-growth tier. Unit economics differ: ad-tier subs carry lower subscription ARPU but ad revenue at ~70% incremental margin lifts blended contribution above the standard tier by year two of a sub's life.
41+
42+
---
43+
44+
**`{{whats_priced_in}}`**
45+
46+
At $620, NFLX trades at 28x consensus '26 EPS of $22.10. Consensus models 11% revenue growth and 23% operating margin in '27 — implying the Street is pricing in the subscription business compounding low-teens with modest margin expansion. Sellside ad-tier revenue estimates cluster around $4-5B for '27 (consensus mean $4.6B). Our '27 model puts ad revenue at $8.2B (+78% vs. consensus) on higher ad-tier sub adds and sustained ARPU. EPS divergence: our $29.50 vs. consensus $24.80, a +19% delta.
47+
48+
---
49+
50+
**`{{scenario_table}}`**
51+
52+
| | Bear (20%) | Base (55%) | Bull (25%) |
53+
|---|---|---|---|
54+
| Revenue '27 | $42B | $52B | $61B |
55+
| Revenue growth | +6% | +14% | +20% |
56+
| EBIT margin | 22% | 28% | 32% |
57+
| EPS '27 | $19.50 | $29.50 | $38.20 |
58+
| Exit multiple | 22x | 28x | 35x |
59+
| Price target | $430 | $785 | $1,205 |
60+
| Return | -31% | +27% | +94% |
61+
62+
Prob-weighted return: +18% · Upside / downside: 2.4x
63+
64+
---
65+
66+
**`{{bull_narrative}}`**
67+
68+
Ad-tier inflects faster than we model. Disney+ pulls back on ad-tier pricing competition, leaving NFLX as the premium ad-supported inventory option for upfront buyers. Live programming (NFL, boxing, WWE) drives ad-tier mix of new signups above 70%, and ad CPMs sustain in the $40s as inventory stays scarce relative to demand. Content cost discipline holds — total content spend stays flat at $17B even as subs grow — and operating margin reaches 32% by '27. The Street rerates the stock to 35x as ad revenue crosses 20% of total, reclassifying NFLX from subscription business to dual-revenue media platform. EPS compounds 25%+ for three years.
69+
70+
---
71+
72+
**`{{base_narrative}}`**
73+
74+
Ad-tier grows roughly in line with current trajectory and reaches 50M+ subs by '27. ARPU holds at $9-10 as content investment in live and originals supports pricing. Content amortization peaks in '25 and rolls off, lifting operating margin to 28% by '27 even with $18-19B of content spend. Subscription business compounds high single digits globally with the bulk of net adds from APAC and LatAm at lower ARPU. The Street partially rerates the stock as ad mix exceeds 15%, multiple expands to 28x — in line with current level but on materially higher EPS.
75+
76+
---
77+
78+
**`{{bear_narrative}}`**
79+
80+
Disney+ and Amazon's Prime Video ad tier compete aggressively on price; Disney+ ad-tier subs cross 100M globally by end-'26 and Amazon bundles ad-supported streaming into Prime at no incremental cost. Ad-tier CPMs compress 25% to the high $20s as inventory floods the market and brand advertisers consolidate spend on retail media platforms (Amazon, Walmart Connect) rather than streaming. NFLX ad revenue stalls at $3-3.5B for '27 vs. street $4.6B. Content spend creeps to $20B as the live programming push (NFL, boxing) proves more expensive to renew than initial deals suggested. Operating margin compresses to 22% as fixed content costs deleverage on slower revenue growth. The multiple compresses to 22x — Disney's current multiple — as the market reclassifies NFLX as a mature subscription business with declining incremental returns on content spend. Stock retraces to the low $400s.
81+
82+
---
83+
84+
**`{{catalysts_table}}`**
85+
86+
| Event | Date | Expected Impact |
87+
|---|---|---|
88+
| Q2 '26 earnings — ad-tier sub disclosure | Jul '26 | Ad-tier sub count vs. our 45M target |
89+
| Upfront ad commitments | Apr-May '26 | Total committed dollars; vs. $1B+ '25 baseline |
90+
| NFL Christmas Day games viewership | Dec '26 | Concurrent viewers; ad-load testing |
91+
| FY27 guidance | Jan '27 | First explicit ad revenue guide |
92+
93+
---
94+
95+
**`{{risks_table}}`**
96+
97+
| Risk | Mitigant | Tripwire |
98+
|---|---|---|
99+
| Ad-tier ARPU compression | Premium inventory (live sports) supports CPMs | Disclosed ad ARPU < $8 in any quarter |
100+
| Content cost re-acceleration | Management explicit guide of $17B '26 cap | Content spend > $19B in any year |
101+
| Competitive ad-tier launch from Amazon | Amazon ad-tier already live; share gains modest | NFLX ad-tier net adds < 5M in any quarter |
102+
| Subscription growth stalls in APAC | Pricing flexibility, mobile-only tier | Net adds < 4M globally in two consecutive quarters |
103+
| Multiple compression on rate environment | EPS growth outpaces multiple compression risk | Multiple < 24x with no operational miss |
104+
105+
---
106+
107+
**`{{position_management}}`**
108+
109+
Suggested sizing: 4% NAV — high conviction × 2.4x asymmetry. Entry: current ($620) or scale-in below $590 on multiple compression. Stop / reduce: trim 50% if ad-tier ARPU prints below $8 in any quarter; full exit if content spend guide steps above $19B.
110+
111+
---
112+
113+
**`{{monitoring_kpis}}`**
114+
115+
1. Ad-tier subscriber count (quarterly disclosure)
116+
2. Ad-tier ARPU or implied ARPU (calc: ad revenue / avg ad-tier subs)
117+
3. Content cash spend YTD vs. annual guide
118+
4. Operating margin (quarterly) — trajectory to 28% by '27
119+
5. Upfront commitment dollars (annual) — vs. prior year
120+
121+
---
122+
123+
## Why this example works
124+
125+
- **Variant view is specific and contradictable.** It names a number (20%+ revenue contribution by '27) and a divergence (Street models single-digit). A PM can disagree with it precisely.
126+
- **Every thesis bullet has a "wrong if".** None of them are unfalsifiable platitudes.
127+
- **Bear case names competitors and mechanisms.** Disney+, Amazon, retail media, NFL renewal costs. Not "competition intensifies".
128+
- **Tripwires are observable.** "Disclosed ad ARPU < $8 in any quarter" is a data point the analyst can monitor; "macro deteriorates" is not.
129+
- **No padding.** No founding history, no "in an ever-evolving streaming landscape", no closing summary paragraph.
130+
131+
When you draft a real memo, match this density and specificity, not the surface aesthetics. The aesthetics come from the template; the substance comes from the thinking.

0 commit comments

Comments
 (0)