← Back to Daily Brief

How It Works

56 Maple Daily Brief

The Daily Brief is a market dashboard delivered by email after US market close. It tracks 49 macro indicators across bonds, credit, private credit, equities, currencies, commodities, and real estate. The goal is a five-minute read that tells a long-term investor whether anything changed that matters.

What it tracks

Category What it captures Example metrics
Bonds Fed expectations, yield curve shape, real rates, duration exposure 2Y Yield, 10Y Yield, TLT, Yield Curve 2s10s
Credit High-yield and investment-grade spread direction, risk appetite HYG, LQD, HY Spread
Private Credit Direct lending health, leveraged loan stress, BDC valuations BKLN, BIZD, OBDC, HYG/LQD ratio
US Equities Market direction, breadth, volatility S&P 500, Nasdaq, VIX, Russell 2000
Currencies & Gold Dollar strength, safe-haven demand, crypto DXY, EUR/USD, Gold, Bitcoin
Commodities Growth signals, inflation inputs, supply disruption Crude Oil, Copper, Natural Gas
Institutional Flows Fed balance sheet, labor market, cash positioning Fed Total Assets, Jobless Claims, Money Market Funds
Real Estate Proxies REIT valuations, housing activity, mortgage conditions VNQ, Mortgage Rate, Housing Starts, Case-Shiller

Metrics are selected for what they reveal about financial conditions, not because they are popular or commonly tracked. Each metric has a specific role on the dashboard and a reason it is there instead of something else. Some categories use ETF price proxies rather than underlying spread or rate data. This is a deliberate trade-off: ETFs provide daily pricing from a free data source, while actual credit spreads require paid terminal subscriptions.

How the data moves

┌──────────────┐     ┌──────────────┐     ┌──────────────┐
│  Yahoo       │     │  Python      │     │  Claude      │
│  Finance API │────►│  Pipeline    │────►│  Sonnet      │
│  + FRED API  │     │              │     │  (interpret)  │
└──────────────┘     └──────┬───────┘     └──────┬───────┘
                            │                     │
                     ┌──────▼───────┐     ┌──────▼───────┐
                     │  Charts      │     │  Market      │
                     │  (matplotlib)│     │  Commentary  │
                     └──────┬───────┘     └──────┬───────┘
                            │                     │
                            └──────┬──────────────┘
                                   │
                            ┌──────▼───────┐
                            │  HTML Email  │
                            │  (Mailgun)   │
                            └──────────────┘

The entire pipeline is a single run.py script. It fetches data from Yahoo Finance and FRED, generates charts with matplotlib, passes the numbers to Claude Sonnet for interpretation, assembles the email, and sends it via Mailgun. It runs on a GitHub Actions cron job at market close. There is no database, no web server, no queue, no container orchestration.

How AI is used

Claude Sonnet receives the day's metric values, change statistics, and chart context as structured input. It generates a 300 to 500 word investment memo with sections for each asset class, assigns a conviction level to each section based on data strength, applies a regime label based on cross-asset signals, and identifies the single most important variable to watch.

The model does not fetch data, pick metrics, or decide what to track. It does not use its training knowledge to fill gaps. If a metric has no data that day, the section is skipped entirely. It does not make investment recommendations or trade suggestions. Each run is stateless. The model has no memory of previous days.

The prompt is a YAML configuration file that defines directional thresholds, preventing the model from calling a 3 basis point move "surging." Regime labels have explicit definitions. The model matches conditions to labels rather than freelancing. Output is capped at 500 words with strict formatting rules. The system prompt explicitly prohibits fabricating data or inferring from training knowledge.

From the interpretation prompt — directional thresholds:

Rates (%, bps):            |change| > 5 bps  → "rising" / "falling"
Equities (%):              |change| > 0.5%   → "rising" / "falling"
Spreads (bps):             |change| > 10 bps → "widening" / "tightening"
Commodities (%):           |change| > 1.0%   → "rising" / "falling"
Private Credit ETFs ($):   |change| > 0.5%   → "rising" / "falling"
Private Credit Ratios:     |change| > 0.005  → "rising" / "falling"

Moves inside these bands → "stable". No directional language allowed.

From the interpretation prompt — regime definitions:

Tightening:   rising rates + widening credit spreads + falling BDC/loan prices
Easing:       falling rates + tightening credit spreads + rising BDC/loan prices
Risk-off:     rising rates + falling equities + widening spreads
Risk-on:      falling/stable rates + rising equities + tightening spreads
Reflation:    rising commodities + steepening yield curve + rising equities
Stagflation:  rising rates + rising commodities + falling equities
Late cycle:   flat/inverted curve + tight spreads + narrow equity breadth
Transition:   mixed signals — describe the tension

From the interpretation prompt — output structure (9 sections):

1) Bonds                              [2-3 sentences] [conviction level]
2) Credit                             [2-3 sentences] [conviction level]
3) Private Credit                     [2-3 sentences] [conviction level]
4) Equities                           [2-3 sentences] [conviction level]
5) Commodities                        [2-3 sentences] [conviction level]
6) Flows / Liquidity                  [2-3 sentences] [conviction level]
7) Today's Environment                [2-3 sentences] regime label
8) Practical Investment Implications  [2-3 sentences]
9) One Key Change to Watch            [1 sentence]

How news is sourced

The brief includes relevant market analysis articles alongside the data. The system scans the day's metrics for significant weekly movers, then queries Google News RSS for explanatory coverage. It does not summarize or rewrite articles. It links to them.

The process works in two stages. First, metrics that moved beyond their category threshold are identified as "movers." For each mover, the system builds a targeted search query using the metric name and directional terms, filtered for analysis rather than headline news.

Example: if the 10Y yield rose significantly, the query becomes:

"10 year treasury yield" rise OR rally OR higher OR surge
  analysis OR outlook OR why OR explained OR implications

For categories where nothing moved, the system falls back to thematic queries tuned for a PE investor. These are pre-written search strings designed to surface deal-relevant coverage rather than retail market commentary.

Example thematic queries:

Institutional Flows:
  "private equity fundraising" OR "dry powder" OR "private credit"
  OR "direct lending" OR "BDC" OR "middle market" OR "deal flow"
  OR "CLO" OR "leveraged loan" outlook OR analysis

Real Estate:
  "commercial real estate" OR "CRE" OR "cap rates" OR "CMBS"
  OR "sale leaseback" OR "net lease" OR "construction financing"
  outlook OR analysis

Results are ranked with preferred domains first: FT, Bloomberg, WSJ, PitchBook, Reuters, Barron's. Near-duplicate articles are removed. The system fetches up to 3 articles per mover and 1 per thematic category.

How it's built

market-brief/
├── run.py                  ← entry point
├── models.py               ← Pydantic metric model
├── metrics.py              ← metric registry (49 metrics)
├── charts.py               ← matplotlib charts + stats tables
├── interpreter.py          ← Claude Sonnet integration
├── emailer.py              ← Mailgun HTTP API client
├── subscribers.py          ← mailing list management
├── prompts/
│   └── interpretation.yaml ← AI prompt configuration
├── fetchers/
│   ├── yahoo.py            ← yfinance data fetch
│   ├── fred.py             ← FRED API data fetch
│   └── mock.py             ← synthetic fallback for dev
├── templates/
│   ├── preview.html        ← email/web template
│   └── index.html          ← archive page
└── output/
    ├── YYYY-MM-DD/         ← daily briefs + charts
    └── index.html          ← archive index

Adding a metric means editing one file: metrics.py. One block of configuration, no code changes elsewhere. The metric registry is the control panel. Everything downstream — fetching, charting, interpretation — reads from it.

Dependencies are yfinance, pandas, matplotlib, Pydantic, and the Anthropic SDK. There is no framework, no ORM, no build step, no Docker. The pipeline runs on GitHub Actions and the archive is hosted on GitHub Pages.

The Daily Brief is sent weekdays after market close. Past editions are available in the archive.