|
| 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 |
0 commit comments