checking system…
Docs / Demo — Stock analysis
Walkthrough: trading_intelligence arena against NVDA on a sample date.

Stock Analysis Demo — fomo2 + yahoo_finance + trtools2 → mastermind → trade signal

What this does

One command turns a stock ticker into an actionable trade signal grounded in real, live data:

  1. Picks the latest fomo2 markdown report (news + financial narrative).
  2. Pulls Yahoo Finance data (live quote, recent news, market context).
  3. Pulls trtools2 / QuestDB (recent OHLCV bars + a small set of technical indicators).
  4. Concatenates everything into a single ≤ 8 KB markdown brief.
  5. Feeds the brief to the mastermind arena (4 specialists + judge, real Ollama Cloud LLM).
  6. Maps the resulting Decision to a TradeSignal (BUY / SELL / HOLD with confidence + horizon).

Prereqs

  • Python: pip install -e .[knowledge] from the MAF repo root.
  • Ollama Cloud key in .env as OLLAMA_API_KEY=....
  • QuestDB running on localhost:8812 (PG-wire). For a dev box the existing questdb container handles this. The demo degrades gracefully if it's down — bars + indicators slots become None with an entry in pack.errors.
  • fomo2 reports in ../fomo2/output/analyze_*.md. Optional — if the dir is empty, the fomo2 slot becomes None.
  • Yahoo Finance is reached via yfinance (no API key needed).
  • The mastermind also reads optional Redis (REDIS_URL) and Neo4j (NEO4J_URI) when set, but the demo runs without them.

The 1-line command

cd /home/trbck/workspace/MAF
PYTHONPATH=src python -m maf.arenas.mastermind.stock_analysis_cli \
    --ticker AAPL --horizon 24h

Mock-agent fast path (no LLM calls, ~1s):

PYTHONPATH=src python -m maf.arenas.mastermind.stock_analysis_cli \
    --ticker AAPL --no-real-agents

What the output looks like

Real run (live Ollama Cloud, 30–90s wall) prints a header to stdout:

==========================================================================================
STOCK_ANALYSIS — AAPL (horizon=24h)
==========================================================================================
  recommendation : HOLD AAPL 24h
  confidence     : 0.620  dissent: 0.300
  trade_signal   : HOLD  confidence=0.527
  pack_md_chars  : 4218  sources_with_data=6
  pack_path      : /tmp/maf_stock_pack_AAPL_20260507T093412Z.md
------------------------------------------------------------------------------------------
REASONING (truncated to 600 chars):
The fundamentals point to a steady AAPL position over the next 24h: live price
$195.42 sits comfortably in the upper half of the 52w range; RSI_14=62.5 is
elevated but not extreme; the latest fomo2 narrative highlights buyback +
guidance-raise momentum. RiskSkeptic flags that the VIX is at 13.2 (near multi-year
lows) which historically precedes mean-reverting volatility expansion — short-dated
upside is therefore capped. Memory citation 9c4a... (HOLD AAPL 24h, 2026-05-04)
directly analogous and supports HOLD. Recommend HOLD; a single-day window does
not justify a fresh long given the elevated RSI.
==========================================================================================

Plus a full JSON report at .boil/iterations/iter-011/artifacts/stock_analysis_<TICKER>.json containing:

  • pack — the full StockPack (each adapter's raw return)
  • pack_md_chars + pack_md_path — the rendered brief (truncated to ≤ 8000 chars)
  • decision — the mastermind Decision (recommendation, confidence, dissent, reasoning, argument_tree, arena_votes, memory_citations, graph_citations)
  • trade_signal{signal, confidence, horizon, rationale} consumer-side mapping
  • errors — any per-source fetch failures

How it works

                   ┌─ fomo2_report  ─────┐
                   │  (latest .md file)  │
ticker  ─►  gather ┼─ yahoo_quote/news/  ┼─►  render_pack_as_markdown
            (par-  │   overview          │       │
             allel)│   (yfinance)        │       ▼
                   ├─ questdb bars       │   /tmp/maf_stock_pack_<T>_<ts>.md
                   │   (last N bars)     │       │
                   └─ technical          │       ▼
                       indicators        │   MastermindArena.run(target=...)
                       (sma, ema, rsi…)  │       │
                                         │       ▼
                                         │   Decision (recommendation,
                                         │              confidence,
                                         │              argument_tree,
                                         │              memory_citations…)
                                         │       │
                                         │       ▼
                                         └►  decision_to_trade_signal
                                                 │
                                                 ▼
                                             TradeSignal {BUY|SELL|HOLD,
                                                          confidence,
                                                          horizon,
                                                          rationale}

Each gather step is wrapped in a fault-tolerant _safe_fetch_* shim that returns an _AdapterError sentinel on failure rather than raising — the brief still renders if a source is down. The mastermind itself follows the iter-7 phase graph: frame → gather (specialists) → graph_query → memory_retrieve → debate → judge → emit.

How to extend

  • Add a data source — write a _safe_fetch_<name> async function in stock_analysis.py, add a coroutine to the coros list in gather_stock_pack, add a slot to StockPack, wire a _render_<name> block into render_pack_as_markdown. The pack budget is PACK_MARKDOWN_MAX_CHARS = 8000 total — section caps are SECTION_MAX_CHARS = 2000 each, fomo2 excerpt at FOMO2_EXCERPT_MAX_CHARS = 1500.
  • Swap the question template_build_question(ticker, horizon) in stock_analysis_cli.py. Keep the prompt explicit about what the source document contains.
  • Use it as a librarygather_stock_pack(ticker) + render_pack_as_markdown(pack) are pure async / pure functions; you can call them outside the CLI.

Honest limitations

  • fomo2 report selection is naive — we use the latest report regardless of whether it mentions the ticker. T-0066 (filed) wants topical filtering.
  • trtools2 indicators — uses pandas-ta defaults (sma, ema, rsi, atr). The set is configurable via --indicators sma_20 ema_50 ....
  • No live trading — TradeSignal is advisory. Wiring it to a paper-trade engine is a separate concern (see oddsoddy for that pattern).
  • Mastermind judge confidence is conservative — typical decisions land 0.4–0.7. Iter-9 backtest showed mastermind beats every constituent on a 14d window but can lose on noisier 7d windows (see T-0063).