name: session-news-brief description: Use when the user wants a session-start brief, asks what's happening on a symbol, wants overnight market-moving news, or wants swing-trade candidates. Read-only.
Session News Brief
Combines economic + earnings calendar (Calix), a fan-out across three news APIs with cross-publisher dedup, AlphaVantage macro economic context + NLP sentiment enrichment + top movers, and a swing-candidates section that surfaces positive-carry setups at technical extremes.
The skill never executes — output is informational. Use pre-trade-checklist before entering any trade the brief surfaces.
Prerequisites & first-run setup
This is the most setup-heavy skill in the bundle. Before the first invocation, verify:
trading-agent-skills-newsCLI is on PATH. Test withtrading-agent-skills-news --help. If not found: "Install the Python package — from the agent-trading-skills repo, runpip install -e .in a venv your harness can see."mt5-mcpserver is connected. Verify withmcp__mt5-mcp__ping. The brief usesget_positions(tier-2 watchlist),get_symbols, andget_rates(D1 bars for ATR/RSI swing candidates).Calix is reachable at
https://calix.fintrixmarkets.com. If unreachable, the calendar overlay degrades withCALIX_DEGRADEDand the brief still runs.At least one news API key is set as an environment variable. Check via the agent's environment:
FINNHUB_API_KEY,MARKETAUX_API_KEY,FOREXNEWS_API_KEY. Each one is independent — the brief works with any subset, missing keys surface asMISSING_NEWS_API_KEYflags. If none are set, walk the user through this:"The news section needs at least one of these API keys (all have free tiers):
- Finnhub: https://finnhub.io
- Marketaux: https://marketaux.com
- ForexNews: https://forexnewsapi.com
After signing up, set the key. Recommended (cross-session, Windows-friendly): create
~/.trading-agent-skills/.envwith one line per key, e.g.FINNHUB_API_KEY=abc123. The CLI auto-loads this file. Alternatively, export in your shell (export FINNHUB_API_KEY=...on bash,$env:FINNHUB_API_KEY=\"...\"on PowerShell)."~/.trading-agent-skills/config.tomlis auto-generated on first run. Default watchlist isXAUUSD / XAGUSD / USOIL / UKOIL / NAS100; the user can editwatchlist.defaultandwatchlist.base_universe.AlphaVantage MCP server (optional). If the
alphavantageMCP server is configured, the brief gains three sections: macro economic context (GDP, CPI, yields, unemployment, etc.), NLP sentiment scores on news articles, and top equity gainers/losers/most-active. If the server isn't configured, these sections are silently omitted — the brief runs unchanged.
If (1) or (2) fail, walk the user through the fix before bundling MCP outputs. (4) is non-fatal — proceed and surface the flag in the result.
When to invoke
Trigger phrases:
- "morning brief" / "news brief for the session"
- "what's happening on [symbol]"
- "any news on [symbol] in the last [N] hours"
- "any swing setups today"
- "show me overnight movers"
Don't invoke for routine market-data questions (mt5-market-data); don't invoke for sizing or pre-trade gating (use the dedicated skills).
Inputs (collect from user if implied; both optional)
- Watchlist — explicit list. If omitted, the skill resolves via the 5-tier order below.
- Lookback hours — defaults to 12 (morning brief) / 1 (intra-session refresh).
Watchlist resolution (deduped union, capped at config.watchlist.max_size)
- Explicit input — what the user passed
- Open positions — from
mcp__mt5-mcp__get_positions - Calendar-driven — symbols whose currencies hit the next-8h Calix economic events; index symbols for index-constituent earnings
- Volatility-ranked — top-N from
config.watchlist.base_universeby ATR(14) on D1 expressed as % of price (compute viaget_rates(D1, 30)per symbol) - Static fallback —
config.watchlist.default(XAUUSD / XAGUSD / USOIL / UKOIL / NAS100 by default)
Workflow
1. Gather symbol metadata + bars
For each candidate symbol (after watchlist resolution):
mcp__mt5-mcp__get_symbols(category=...)→ currency_base, currency_profit, swap_long, swap_short, categorymcp__mt5-mcp__get_rates(symbol, timeframe="D1", count=30)→ bars for ATR(14) + RSI(14) + EMA(20)
2. Gather Calix calendar
curl -s "https://calix.fintrixmarkets.com/v1/calendar/economic/upcoming?currencies=USD,EUR&impact=High&limit=20"
curl -s "https://calix.fintrixmarkets.com/v1/calendar/earnings/upcoming?limit=30"
If Calix is unreachable or returns 5xx, set calix.economic_stale = true (and/or earnings_stale) — the brief will surface a CALIX_DEGRADED flag rather than silently passing.
2b. Fan out AlphaVantage MCP tools (optional, parallel)
If the AlphaVantage MCP server is configured, call these tools in parallel:
Macro indicators (one call each):
mcp__alphavantage__TREASURY_YIELD(interval="daily", maturity="10year")mcp__alphavantage__FEDERAL_FUNDS_RATE(interval="daily")mcp__alphavantage__CPI(interval="monthly")mcp__alphavantage__INFLATION(interval="annual")mcp__alphavantage__UNEMPLOYMENT(interval="monthly")mcp__alphavantage__NONFARM_PAYROLL(interval="monthly")mcp__alphavantage__REAL_GDP(interval="quarterly")mcp__alphavantage__RETAIL_SALES(interval="monthly")mcp__alphavantage__DURABLES(interval="monthly")
Sentiment (one call per watchlist symbol):
mcp__alphavantage__NEWS_SENTIMENT(tickers=<symbol>, time_from=<lookback_iso>)
Top movers (single call):
mcp__alphavantage__TOP_GAINERS_LOSERS()
If any AV call fails or the MCP server is not configured, skip silently — existing pipeline runs unchanged.
Include the results in the bundle JSON under "macro_indicators", "av_sentiment", and "top_movers" keys respectively.
3. Fan out to news providers
The CLI fetches news itself if the bundle omits the news key — this lets the agent run the brief with one piping call. Provide API keys via env vars:
| Provider | Env var |
|---|---|
| Finnhub | FINNHUB_API_KEY |
| Marketaux | MARKETAUX_API_KEY |
| ForexNews | FOREXNEWS_API_KEY |
API keys never live in config.toml. A missing key for one provider doesn't block the others — the brief surfaces a MISSING_NEWS_API_KEY flag and per-provider health status so the user knows which sources contributed.
The CLI also auto-loads a .env file. Search order: --env-file <path> if passed → ~/.trading-agent-skills/.env → ./.env (CWD). Real shell env vars always win. .env.example at the repo root is the template; .env is gitignored. This is the recommended path on Windows / PowerShell, where bash export doesn't apply.
If you've already fetched the news upstream (e.g. you ran the providers in parallel via a custom script), pre-fill news.articles_by_provider + news.provider_status in the bundle to skip the in-CLI fan-out.
4. Build the bundle
{
"now_utc": "2026-04-29T21:00:00+00:00",
"lookahead_hours": 4,
"lookback_hours": 12,
"explicit_watchlist": ["UKOIL"],
"open_position_symbols": ["XAUUSD"],
"calendar_event_currencies": ["USD", "EUR"],
"earnings_constituent_indices": ["NAS100"],
"volatility_ranked": ["XAGUSD", "BTCUSD"],
"max_size": 8,
"symbol_meta": {
"UKOIL": {
"currency_base": "UKOIL",
"currency_profit": "USD",
"category": "commodities",
"swap_long": "125",
"swap_short": "-150"
}
},
"bars_by_symbol": {
"UKOIL": [
{"time": "...", "open": "...", "high": "...", "low": "...", "close": "...", "volume": 0}
]
},
"calix": {
"economic_events": [<raw Calix /v1/calendar/economic shapes>],
"earnings_entries": [<raw Calix /v1/calendar/earnings shapes>],
"economic_stale": false,
"earnings_stale": false
}
}
5. Run the brief
echo '<bundle>' | python -m trading_agent_skills.cli.news
Or via entry point: trading-agent-skills-news.
6. Render
{
"generated_at_utc": "...",
"watchlist": ["UKOIL", "XAUUSD", "NAS100", ...],
"watchlist_description": "5/8 symbols: 1 from open positions, 2 from calendar, 2 from default",
"watchlist_by_tier": {...},
"calendar_by_symbol": {
"UKOIL": [
{"kind": "economic", "title": "EIA Crude Inventories", "when_utc": "...",
"impact": "Medium", "detail": {"currency": "USD"}}
]
},
"news_by_symbol": {
"UKOIL": [
{"title": "OPEC+ holds production cuts",
"publisher": "Reuters",
"sources": ["finnhub/Reuters", "marketaux/Yahoo"],
"url": "...",
"published_at_utc": "...",
"impact": "high",
"summary": "Group leaves output unchanged."}
]
},
"swing_candidates": [
{"symbol": "UKOIL", "direction": "long_carry",
"rsi_14": "28.5", "swap_long": "125", "thesis": "..."}
],
"health": {"finnhub": "ok", "marketaux": "no_api_key", "forexnews": "ok",
"calix_economic": "ok", "calix_earnings": "ok"},
"flags": ["MISSING_NEWS_API_KEY"],
"notes": [...]
}
Render in this order so the user can scan top-down:
Morning brief — 5 symbols watched
Watchlist: UKOIL, XAUUSD, NAS100, EURUSD, USOIL
(1 from open positions, 2 from calendar, 2 from default)
⚡ Swing candidates (positive carry + technical extreme):
UKOIL (D1 RSI 28, oversold; long pays $125/lot/night)
Thesis: mean-reversion bounce on a positive-carry side.
Verify Strait of Hormuz / OPEC+ headlines before entry.
📅 Calendar (next 4h):
UKOIL — EIA Crude Inventories (Medium, 22:30 UTC)
📰 News (last 12h):
UKOIL: OPEC+ holds production cuts — 3 sources [Reuters / Yahoo / Bloomberg]
"Group leaves output unchanged."
XAUUSD: FOMC holds rates — 2 sources [Reuters / Bloomberg]
"Fed signals patience on cuts; dollar firms."
⚠ Health: Marketaux API key missing — Finnhub + ForexNews shown.
Health and degraded modes
AV_MACRO_STALE— one or more macro indicators are older than their expected update cadence (e.g. GDP more than 120 days old). The reading is still shown but flagged.MISSING_NEWS_API_KEY— at least one provider's env var is unset. Set the missing key(s) for fuller coverage.NEWS_PROVIDER_DEGRADED— at least one provider returned an HTTP error or timed out. Re-run after a few minutes; if persistent, that provider may have changed its API.CALIX_DEGRADED— Calix self-reportedstale: trueor returned a 5xx. The calendar-overlay section is from the prior cache; news-proximity in the checklist will WARN until it refreshes.INDICATOR_DATA_INSUFFICIENT— fewer than 21 D1 bars (or no symbol meta) for one or more watchlist symbols → that symbol is omitted from the swing-candidates evaluation. Pull longer history or remove from base universe.
Common pitfalls
- Currency vs ticker tagging. Finnhub returns ticker symbols in
related; Marketaux returnsentitieswith symbols; ForexNews returns currency-pair codes (["XAU-USD", "EUR-USD"]). The orchestrator handles all three: explicit symbol → canonical-pair (XAU-USD↔XAUUSD) → index-constituent ticker (AAPL→NAS100) → bare-currency-tag intersection → article-keyword intersection → word-bounded topic vocab on title+summary (oil/crude/gold/silver). The substring-currency fallback was removed in 2026-05 because"USD"appears in nearly every forex headline and over-attributed every USD-quoted symbol with every USD-tagged article. - Index constituent expansion. When an index (e.g.
NAS100) is in the watchlist, the CLI fans out to Marketaux with the index's constituent equity tickers (AAPL, MSFT, GOOG, …) — the API doesn't recogniseNAS100as an entity. The relevance matcher then routes those equity-tagged articles back to the index. Constituent maps live insymbol_meta._INDEX_CONSTITUENTS; expand them when adding indices to the watchlist. - Swap rates must come from the broker. Don't paraphrase from news — ask
get_symbolsand pass the rawswap_long/swap_shortDecimals. The "+$125/lot/night" claim in a UKOIL thesis is only credible if it matches the broker's actual swap rate at the time of the brief. - Indicator math needs at least 21 D1 bars (RSI(14) needs 15, EMA(20) needs 20). Pull
get_rates(D1, 30)for safety. Lower-timeframe ATR/RSI are not used here — the swing-candidates section is intentionally a daily-bar lens. - Dedup across providers uses URL canonicalisation first (strips
utm_*,fbclid, normalises host/scheme), then headline Levenshtein ratio (default 0.85). Same Reuters story syndicated by Yahoo collapses to one row with both sources listed. - Cache TTL is 60s for both Calix and news fan-out. Re-running the brief within 60s returns cached data — fine for "show me again" follow-ups, suspicious if the user expects fresh post-FOMC data. Bypass by deleting
~/.trading-agent-skills/news_cache/and~/.trading-agent-skills/calix_cache/. - No execution. This skill never calls a mutating MCP tool. Surfacing a swing candidate is not a recommendation to enter — route through
pre-trade-checklistfor the discipline gates.