1121 lines
50 KiB
Markdown
1121 lines
50 KiB
Markdown
# Agent Data & Information Flows
|
||
|
||
This document describes how each agent in the TradingAgents framework collects
|
||
data, processes it, and sends it to an LLM for analysis or decision-making.
|
||
It also records the default model and **thinking modality** (quick / mid / deep)
|
||
used by every agent.
|
||
|
||
> **Source of truth** for LLM tier defaults: `tradingagents/default_config.py`
|
||
|
||
---
|
||
|
||
## Table of Contents
|
||
|
||
1. [Thinking-Modality Overview](#1-thinking-modality-overview)
|
||
2. [Trading Pipeline Flow](#2-trading-pipeline-flow)
|
||
3. [Scanner Pipeline Flow](#3-scanner-pipeline-flow)
|
||
4. [Per-Agent Data Flows](#4-per-agent-data-flows)
|
||
- [4.1 Market Analyst](#41-market-analyst)
|
||
- [4.2 Fundamentals Analyst](#42-fundamentals-analyst)
|
||
- [4.3 News Analyst](#43-news-analyst)
|
||
- [4.4 Social Media Analyst](#44-social-media-analyst)
|
||
- [4.5 Bull Researcher](#45-bull-researcher)
|
||
- [4.6 Bear Researcher](#46-bear-researcher)
|
||
- [4.7 Research Manager](#47-research-manager)
|
||
- [4.8 Trader](#48-trader)
|
||
- [4.9 Aggressive Debator](#49-aggressive-debator)
|
||
- [4.10 Conservative Debator](#410-conservative-debator)
|
||
- [4.11 Neutral Debator](#411-neutral-debator)
|
||
- [4.12 Risk Manager](#412-risk-manager)
|
||
- [4.13 Geopolitical Scanner](#413-geopolitical-scanner)
|
||
- [4.14 Market Movers Scanner](#414-market-movers-scanner)
|
||
- [4.15 Sector Scanner](#415-sector-scanner)
|
||
- [4.16 Industry Deep Dive](#416-industry-deep-dive)
|
||
- [4.17 Macro Synthesis](#417-macro-synthesis)
|
||
5. [Tool → Data-Source Mapping](#5-tool--data-source-mapping)
|
||
6. [Memory System](#6-memory-system)
|
||
|
||
---
|
||
|
||
## 1. Thinking-Modality Overview
|
||
|
||
The framework uses a **3-tier LLM system** so that simple extraction tasks run
|
||
on fast, cheap models while critical judgment calls use the most capable model.
|
||
|
||
| Tier | Config Key | Default Model | Purpose |
|
||
|------|-----------|---------------|---------|
|
||
| **Quick** | `quick_think_llm` | `gpt-5-mini` | Fast extraction, summarization, debate positions |
|
||
| **Mid** | `mid_think_llm` | *None* → falls back to quick | Balanced reasoning with memory |
|
||
| **Deep** | `deep_think_llm` | `gpt-5.2` | Complex synthesis, final judgments |
|
||
|
||
Each tier can have its own `_llm_provider` and `_backend_url` overrides.
|
||
All are overridable via `TRADINGAGENTS_<KEY>` env vars.
|
||
|
||
### Agent → Tier Assignment
|
||
|
||
| # | Agent | Tier | Has Tools? | Has Memory? | Tool Execution |
|
||
|---|-------|------|-----------|-------------|----------------|
|
||
| 1 | Market Analyst | **Quick** | ✅ | — | LangGraph ToolNode |
|
||
| 2 | Fundamentals Analyst | **Quick** | ✅ | — | LangGraph ToolNode |
|
||
| 3 | News Analyst | **Quick** | ✅ | — | LangGraph ToolNode |
|
||
| 4 | Social Media Analyst | **Quick** | ✅ | — | LangGraph ToolNode |
|
||
| 5 | Bull Researcher | **Mid** | — | ✅ | — |
|
||
| 6 | Bear Researcher | **Mid** | — | ✅ | — |
|
||
| 7 | Research Manager | **Deep** | — | ✅ | — |
|
||
| 8 | Trader | **Mid** | — | ✅ | — |
|
||
| 9 | Aggressive Debator | **Quick** | — | — | — |
|
||
| 10 | Conservative Debator | **Quick** | — | — | — |
|
||
| 11 | Neutral Debator | **Quick** | — | — | — |
|
||
| 12 | Risk Manager | **Deep** | — | ✅ | — |
|
||
| 13 | Geopolitical Scanner | **Quick** | ✅ | — | `run_tool_loop()` |
|
||
| 14 | Market Movers Scanner | **Quick** | ✅ | — | `run_tool_loop()` |
|
||
| 15 | Sector Scanner | **Quick** | ✅ | — | `run_tool_loop()` |
|
||
| 16 | Industry Deep Dive | **Mid** | ✅ | — | `run_tool_loop()` |
|
||
| 17 | Macro Synthesis | **Deep** | — | — | — |
|
||
|
||
---
|
||
|
||
## 2. Trading Pipeline Flow
|
||
|
||
```
|
||
┌─────────────────────────┐
|
||
│ START │
|
||
│ (ticker + trade_date) │
|
||
└────────────┬─────────────┘
|
||
│
|
||
┌───────────────────────┬┴┬───────────────────────┐
|
||
▼ ▼ ▼ ▼
|
||
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
|
||
│ Market Analyst │ │ News Analyst │ │ Social Analyst │ │ Fundamentals │
|
||
│ (quick_think) │ │ (quick_think) │ │ (quick_think) │ │ Analyst │
|
||
│ │ │ │ │ │ │ (quick_think) │
|
||
│ Tools: │ │ Tools: │ │ Tools: │ │ Tools: │
|
||
│ • get_macro_regime│ │ • get_news │ │ • get_news │ │ • get_ttm_analysis│
|
||
│ • get_stock_data │ │ • get_global_news │ │ (sentiment) │ │ • get_fundamentals│
|
||
│ • get_indicators │ │ • get_insider_txn │ │ │ │ • get_peer_comp. │
|
||
│ │ │ │ │ │ │ • get_sector_rel. │
|
||
│ Output: │ │ Output: │ │ Output: │ │ • get_balance_sh. │
|
||
│ market_report │ │ news_report │ │ sentiment_report │ │ • get_cashflow │
|
||
│ macro_regime_rpt │ │ │ │ │ │ • get_income_stmt │
|
||
└────────┬─────────┘ └────────┬──────────┘ └────────┬──────────┘ │ Output: │
|
||
│ │ │ │ fundamentals_rpt │
|
||
└─────────────────────┼───────────────────────┘ └────────┬──────────┘
|
||
│ │
|
||
▼ │
|
||
┌─────────────────────────┐◄─────────────────────────────────┘
|
||
│ 4 analyst reports │
|
||
│ feed into debate below │
|
||
└────────────┬─────────────┘
|
||
│
|
||
┌──────────────────┴──────────────────┐
|
||
│ Investment Debate Phase │
|
||
│ │
|
||
│ ┌───────────┐ ┌───────────┐ │
|
||
│ │ Bull │◄────►│ Bear │ │
|
||
│ │ Researcher │ │ Researcher │ │
|
||
│ │ (mid_think)│ │ (mid_think)│ │
|
||
│ │ + memory │ │ + memory │ │
|
||
│ └───────────┘ └───────────┘ │
|
||
│ (max_debate_rounds = 2) │
|
||
└──────────────────┬───────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────┐
|
||
│ Research Manager │
|
||
│ (deep_think + memory) │
|
||
│ │
|
||
│ Reads: debate history, │
|
||
│ 4 analyst reports, │
|
||
│ macro regime │
|
||
│ │
|
||
│ Output: │
|
||
│ investment_plan │
|
||
│ (BUY / SELL / HOLD) │
|
||
└────────────┬─────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────┐
|
||
│ Trader │
|
||
│ (mid_think + memory) │
|
||
│ │
|
||
│ Reads: investment_plan,│
|
||
│ 4 analyst reports │
|
||
│ │
|
||
│ Output: │
|
||
│ trader_investment_plan │
|
||
└────────────┬─────────────┘
|
||
│
|
||
┌──────────────────┴──────────────────┐
|
||
│ Risk Debate Phase │
|
||
│ │
|
||
│ ┌────────────┐ ┌───────────────┐ │
|
||
│ │ Aggressive │ │ Conservative │ │
|
||
│ │ (quick) │ │ (quick) │ │
|
||
│ └──────┬─────┘ └───────┬────────┘ │
|
||
│ │ ┌───────────┐│ │
|
||
│ └───►│ Neutral │◄─────────┘
|
||
│ │ (quick) │ │
|
||
│ └───────────┘ │
|
||
│ (max_risk_discuss_rounds = 2) │
|
||
└──────────────────┬────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────┐
|
||
│ Risk Manager │
|
||
│ (deep_think + memory) │
|
||
│ │
|
||
│ Reads: risk debate, │
|
||
│ trader plan, 4 reports,│
|
||
│ macro regime │
|
||
│ │
|
||
│ Output: │
|
||
│ final_trade_decision │
|
||
└────────────┬─────────────┘
|
||
│
|
||
▼
|
||
┌───────────────┐
|
||
│ END │
|
||
└───────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 3. Scanner Pipeline Flow
|
||
|
||
```
|
||
┌─────────────────────────┐
|
||
│ START │
|
||
│ (scan_date) │
|
||
└────────────┬─────────────┘
|
||
│
|
||
┌────────────────────────────┼────────────────────────────┐
|
||
▼ ▼ ▼
|
||
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
|
||
│ Geopolitical │ │ Market Movers │ │ Sector Scanner │
|
||
│ Scanner │ │ Scanner │ │ │
|
||
│ (quick_think) │ │ (quick_think) │ │ (quick_think) │
|
||
│ │ │ │ │ │
|
||
│ Tools: │ │ Tools: │ │ Tools: │
|
||
│ • get_topic_news │ │ • get_market_ │ │ • get_sector_ │
|
||
│ │ │ movers │ │ performance │
|
||
│ Output: │ │ • get_market_ │ │ │
|
||
│ geopolitical_rpt │ │ indices │ │ Output: │
|
||
│ │ │ │ │ sector_perf_rpt │
|
||
│ │ │ Output: │ │ │
|
||
│ │ │ market_movers_rpt│ │ │
|
||
└────────┬─────────┘ └────────┬─────────┘ └────────┬─────────┘
|
||
│ │ │
|
||
└────────────────────────┼─────────────────────────┘
|
||
│ (Phase 1 → Phase 2)
|
||
▼
|
||
┌─────────────────────────────┐
|
||
│ Industry Deep Dive │
|
||
│ (mid_think) │
|
||
│ │
|
||
│ Reads: all 3 Phase-1 reports │
|
||
│ Auto-extracts top 3 sectors │
|
||
│ │
|
||
│ Tools: │
|
||
│ • get_industry_performance │
|
||
│ (called per top sector) │
|
||
│ • get_topic_news │
|
||
│ (sector-specific searches) │
|
||
│ │
|
||
│ Output: │
|
||
│ industry_deep_dive_report │
|
||
└──────────────┬───────────────┘
|
||
│ (Phase 2 → Phase 3)
|
||
▼
|
||
┌─────────────────────────────┐
|
||
│ Macro Synthesis │
|
||
│ (deep_think) │
|
||
│ │
|
||
│ Reads: all 4 prior reports │
|
||
│ No tools – pure LLM reasoning│
|
||
│ │
|
||
│ Output: │
|
||
│ macro_scan_summary (JSON) │
|
||
│ Top 8-10 stock candidates │
|
||
│ with conviction & catalysts │
|
||
└──────────────┬───────────────┘
|
||
│
|
||
▼
|
||
┌───────────────┐
|
||
│ END │
|
||
└───────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 4. Per-Agent Data Flows
|
||
|
||
Each subsection follows the same structure:
|
||
|
||
> **Data sources → Tool calls → Intermediate processing → LLM prompt → Output**
|
||
|
||
---
|
||
|
||
### 4.1 Market Analyst
|
||
|
||
| | |
|
||
|---|---|
|
||
| **File** | `agents/analysts/market_analyst.py` |
|
||
| **Factory** | `create_market_analyst(llm)` |
|
||
| **Thinking Modality** | **Quick** (`quick_think_llm`, default `gpt-5-mini`) |
|
||
| **Tool Execution** | LangGraph `ToolNode` (graph conditional edge) |
|
||
|
||
**Data Flow:**
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────┐
|
||
│ State Input: company_of_interest, trade_date │
|
||
└────────────────────────┬────────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────┐
|
||
│ 1. get_macro_regime(curr_date) │
|
||
│ → Fetches VIX, credit spreads, yield curve, │
|
||
│ SPY breadth, sector rotation signals │
|
||
│ → Classifies: risk-on / risk-off / transition │
|
||
│ → Returns: Markdown regime report │
|
||
│ Data source: yfinance (VIX, SPY, sector ETFs) │
|
||
└────────────────────────┬────────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────┐
|
||
│ 2. get_stock_data(symbol, start_date, end_date) │
|
||
│ → Fetches OHLCV price data │
|
||
│ → Returns: formatted CSV string │
|
||
│ Data source: yfinance / Alpha Vantage │
|
||
└────────────────────────┬────────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────┐
|
||
│ 3. get_indicators(symbol, indicator, curr_date) │
|
||
│ → Up to 8 indicators chosen by LLM: │
|
||
│ SMA, EMA, MACD, RSI, Bollinger, ATR, VWMA, OBV │
|
||
│ → Returns: formatted indicator values │
|
||
│ Data source: yfinance / Alpha Vantage │
|
||
└────────────────────────┬────────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────┐
|
||
│ LLM Prompt (quick_think): │
|
||
│ "You are a Market Analyst. Classify macro │
|
||
│ environment, select complementary indicators, │
|
||
│ frame analysis based on regime context. │
|
||
│ Provide fine-grained analysis with summary table." │
|
||
│ │
|
||
│ Context sent to LLM: │
|
||
│ • Macro regime classification │
|
||
│ • OHLCV price data │
|
||
│ • Technical indicator values │
|
||
└────────────────────────┬────────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────┐
|
||
│ Output: │
|
||
│ • market_report (technical analysis text) │
|
||
│ • macro_regime_report (risk-on/off classification) │
|
||
└─────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
### 4.2 Fundamentals Analyst
|
||
|
||
| | |
|
||
|---|---|
|
||
| **File** | `agents/analysts/fundamentals_analyst.py` |
|
||
| **Factory** | `create_fundamentals_analyst(llm)` |
|
||
| **Thinking Modality** | **Quick** (`quick_think_llm`, default `gpt-5-mini`) |
|
||
| **Tool Execution** | LangGraph `ToolNode` |
|
||
|
||
**Data Flow:**
|
||
|
||
```
|
||
State Input: company_of_interest, trade_date
|
||
│
|
||
▼
|
||
1. get_ttm_analysis(ticker, curr_date)
|
||
→ Internally calls: get_income_statement, get_balance_sheet, get_cashflow
|
||
→ Computes: 8-quarter trailing metrics (revenue growth QoQ/YoY,
|
||
gross/operating/net margins, ROE trend, debt/equity, FCF)
|
||
→ Returns: Markdown TTM trend report
|
||
Data source: yfinance / Alpha Vantage
|
||
│
|
||
▼
|
||
2. get_fundamentals(ticker, curr_date)
|
||
→ Fetches: P/E, PEG, P/B, beta, 52-week range, market cap
|
||
→ Returns: formatted fundamentals report
|
||
Data source: yfinance / Alpha Vantage
|
||
│
|
||
▼
|
||
3. get_peer_comparison(ticker, curr_date)
|
||
→ Ranks company vs sector peers (1W, 1M, 3M, 6M, YTD returns)
|
||
→ Returns: ranked comparison table
|
||
Data source: yfinance
|
||
│
|
||
▼
|
||
4. get_sector_relative(ticker, curr_date)
|
||
→ Computes alpha vs sector ETF benchmark
|
||
→ Returns: alpha report (1W, 1M, 3M, 6M, YTD)
|
||
Data source: yfinance
|
||
│
|
||
▼
|
||
5. (Optional) get_balance_sheet / get_cashflow / get_income_statement
|
||
→ Raw financial statements
|
||
Data source: yfinance / Alpha Vantage
|
||
│
|
||
▼
|
||
LLM Prompt (quick_think):
|
||
"Call tools in prescribed sequence. Write comprehensive report
|
||
with multi-quarter trends, TTM metrics, relative valuation,
|
||
sector outperformance. Identify inflection points. Append
|
||
Markdown summary table with key metrics."
|
||
│
|
||
▼
|
||
Output: fundamentals_report
|
||
```
|
||
|
||
---
|
||
|
||
### 4.3 News Analyst
|
||
|
||
| | |
|
||
|---|---|
|
||
| **File** | `agents/analysts/news_analyst.py` |
|
||
| **Factory** | `create_news_analyst(llm)` |
|
||
| **Thinking Modality** | **Quick** (`quick_think_llm`, default `gpt-5-mini`) |
|
||
| **Tool Execution** | LangGraph `ToolNode` |
|
||
|
||
**Data Flow:**
|
||
|
||
```
|
||
State Input: company_of_interest, trade_date
|
||
│
|
||
▼
|
||
1. get_news(ticker, start_date, end_date)
|
||
→ Fetches company-specific news articles (past week)
|
||
→ Returns: formatted article list (title, summary, source, date)
|
||
Data source: yfinance / Finnhub / Alpha Vantage
|
||
│
|
||
▼
|
||
2. get_global_news(curr_date, look_back_days=7, limit=5)
|
||
→ Fetches broader macroeconomic / market news
|
||
→ Returns: formatted global news list
|
||
Data source: yfinance / Alpha Vantage
|
||
│
|
||
▼
|
||
3. get_insider_transactions(ticker)
|
||
→ Fetches recent insider buy/sell activity
|
||
→ Returns: insider transaction report
|
||
Data source: Finnhub (primary) / Alpha Vantage
|
||
│
|
||
▼
|
||
LLM Prompt (quick_think):
|
||
"Analyze recent news and trends over the past week.
|
||
Provide fine-grained analysis. Append Markdown table
|
||
organising key points."
|
||
│
|
||
▼
|
||
Output: news_report
|
||
```
|
||
|
||
---
|
||
|
||
### 4.4 Social Media Analyst
|
||
|
||
| | |
|
||
|---|---|
|
||
| **File** | `agents/analysts/social_media_analyst.py` |
|
||
| **Factory** | `create_social_media_analyst(llm)` |
|
||
| **Thinking Modality** | **Quick** (`quick_think_llm`, default `gpt-5-mini`) |
|
||
| **Tool Execution** | LangGraph `ToolNode` |
|
||
|
||
**Data Flow:**
|
||
|
||
```
|
||
State Input: company_of_interest, trade_date
|
||
│
|
||
▼
|
||
1. get_news(query, start_date, end_date)
|
||
→ Searches for company-related social media mentions & sentiment
|
||
→ Returns: formatted news articles related to sentiment
|
||
Data source: yfinance / Finnhub / Alpha Vantage
|
||
│
|
||
▼
|
||
LLM Prompt (quick_think):
|
||
"Analyze social media posts, recent news, public sentiment
|
||
over the past week. Look at all sources. Provide
|
||
fine-grained analysis. Append Markdown table."
|
||
│
|
||
▼
|
||
Output: sentiment_report
|
||
```
|
||
|
||
---
|
||
|
||
### 4.5 Bull Researcher
|
||
|
||
| | |
|
||
|---|---|
|
||
| **File** | `agents/researchers/bull_researcher.py` |
|
||
| **Factory** | `create_bull_researcher(llm, memory)` |
|
||
| **Thinking Modality** | **Mid** (`mid_think_llm`, falls back to `quick_think_llm`) |
|
||
| **Tool Execution** | None — pure LLM reasoning |
|
||
|
||
**Data Flow:**
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────┐
|
||
│ State Input: │
|
||
│ • market_report (from Market Analyst) │
|
||
│ • sentiment_report (from Social Media Analyst) │
|
||
│ • news_report (from News Analyst) │
|
||
│ • fundamentals_report (from Fundamentals Analyst) │
|
||
│ • investment_debate_state.history (debate transcript)│
|
||
│ • investment_debate_state.current_response │
|
||
│ (latest Bear argument to counter) │
|
||
└────────────────────────┬────────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────┐
|
||
│ Memory Retrieval (BM25): │
|
||
│ memory.get_memories(current_situation, n_matches=2) │
|
||
│ → Retrieves 2 most similar past trading situations │
|
||
│ → Returns: matched situation + recommendation │
|
||
│ (Offline, no API calls) │
|
||
└────────────────────────┬────────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────┐
|
||
│ LLM Prompt (mid_think): │
|
||
│ "You are a Bull Researcher. Build evidence-based │
|
||
│ case FOR investing. Focus on growth potential, │
|
||
│ competitive advantages, positive indicators. │
|
||
│ Counter Bear's arguments with specific data. │
|
||
│ Use past reflections." │
|
||
│ │
|
||
│ Context sent: │
|
||
│ • 4 analyst reports (concatenated) │
|
||
│ • Full debate history │
|
||
│ • Bear's latest argument │
|
||
│ • 2 memory-retrieved past situations & lessons │
|
||
└────────────────────────┬────────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────┐
|
||
│ Output: │
|
||
│ • investment_debate_state.bull_history (appended) │
|
||
│ • investment_debate_state.current_response (latest) │
|
||
│ • investment_debate_state.count (incremented) │
|
||
└─────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
### 4.6 Bear Researcher
|
||
|
||
| | |
|
||
|---|---|
|
||
| **File** | `agents/researchers/bear_researcher.py` |
|
||
| **Factory** | `create_bear_researcher(llm, memory)` |
|
||
| **Thinking Modality** | **Mid** (`mid_think_llm`, falls back to `quick_think_llm`) |
|
||
| **Tool Execution** | None — pure LLM reasoning |
|
||
|
||
**Data Flow:**
|
||
|
||
```
|
||
State Input:
|
||
• 4 analyst reports
|
||
• investment_debate_state.history
|
||
• investment_debate_state.current_response (Bull's latest argument)
|
||
│
|
||
▼
|
||
Memory Retrieval:
|
||
memory.get_memories(situation, n_matches=2)
|
||
→ 2 most relevant past situations
|
||
│
|
||
▼
|
||
LLM Prompt (mid_think):
|
||
"You are a Bear Researcher. Build well-reasoned case
|
||
AGAINST investing. Focus on risks, competitive
|
||
weaknesses, negative indicators. Critically expose
|
||
Bull's over-optimism. Use past reflections."
|
||
|
||
Context: 4 reports + debate history + Bull's argument + 2 memories
|
||
│
|
||
▼
|
||
Output:
|
||
• investment_debate_state.bear_history (appended)
|
||
• investment_debate_state.current_response (latest)
|
||
• investment_debate_state.count (incremented)
|
||
```
|
||
|
||
---
|
||
|
||
### 4.7 Research Manager
|
||
|
||
| | |
|
||
|---|---|
|
||
| **File** | `agents/managers/research_manager.py` |
|
||
| **Factory** | `create_research_manager(llm, memory)` |
|
||
| **Thinking Modality** | **Deep** (`deep_think_llm`, default `gpt-5.2`) |
|
||
| **Tool Execution** | None — pure LLM reasoning |
|
||
|
||
**Data Flow:**
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────┐
|
||
│ State Input: │
|
||
│ • investment_debate_state (full Bull vs Bear debate) │
|
||
│ • market_report, sentiment_report, news_report, │
|
||
│ fundamentals_report (4 analyst reports) │
|
||
│ • macro_regime_report (risk-on / risk-off) │
|
||
└────────────────────────┬────────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────┐
|
||
│ Memory Retrieval: │
|
||
│ memory.get_memories(situation, n_matches=2) │
|
||
│ → 2 past similar investment decisions & outcomes │
|
||
└────────────────────────┬────────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────┐
|
||
│ LLM Prompt (deep_think): │
|
||
│ "Evaluate Bull vs Bear debate. Make definitive │
|
||
│ decision: BUY / SELL / HOLD. Avoid defaulting to │
|
||
│ HOLD. Account for macro regime. Summarize key │
|
||
│ points. Provide rationale and strategic actions." │
|
||
│ │
|
||
│ Context: │
|
||
│ • Full debate transcript (all rounds) │
|
||
│ • 4 analyst reports │
|
||
│ • Macro regime classification │
|
||
│ • 2 memory-retrieved past outcomes │
|
||
└────────────────────────┬────────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────┐
|
||
│ Output: │
|
||
│ • investment_debate_state.judge_decision │
|
||
│ • investment_plan (BUY/SELL/HOLD + detailed plan) │
|
||
└─────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
### 4.8 Trader
|
||
|
||
| | |
|
||
|---|---|
|
||
| **File** | `agents/trader/trader.py` |
|
||
| **Factory** | `create_trader(llm, memory)` |
|
||
| **Thinking Modality** | **Mid** (`mid_think_llm`, falls back to `quick_think_llm`) |
|
||
| **Tool Execution** | None — pure LLM reasoning |
|
||
|
||
**Data Flow:**
|
||
|
||
```
|
||
State Input:
|
||
• company_of_interest
|
||
• investment_plan (from Research Manager)
|
||
• 4 analyst reports
|
||
│
|
||
▼
|
||
Memory Retrieval:
|
||
memory.get_memories(situation, n_matches=2)
|
||
→ 2 past similar trading decisions
|
||
│
|
||
▼
|
||
LLM Prompt (mid_think):
|
||
"Analyze investment plan. Make strategic decision:
|
||
BUY / SELL / HOLD. Must end with
|
||
'FINAL TRANSACTION PROPOSAL: BUY/HOLD/SELL'.
|
||
Leverage past decisions."
|
||
|
||
Context: investment_plan + 4 reports + 2 memories
|
||
│
|
||
▼
|
||
Output:
|
||
• trader_investment_plan (decision + reasoning)
|
||
• sender = "Trader"
|
||
```
|
||
|
||
---
|
||
|
||
### 4.9 Aggressive Debator
|
||
|
||
| | |
|
||
|---|---|
|
||
| **File** | `agents/risk_mgmt/aggressive_debator.py` |
|
||
| **Factory** | `create_aggressive_debator(llm)` |
|
||
| **Thinking Modality** | **Quick** (`quick_think_llm`, default `gpt-5-mini`) |
|
||
| **Tool Execution** | None — pure LLM reasoning |
|
||
|
||
**Data Flow:**
|
||
|
||
```
|
||
State Input:
|
||
• risk_debate_state.history (debate transcript)
|
||
• risk_debate_state.current_conservative_response
|
||
• risk_debate_state.current_neutral_response
|
||
• 4 analyst reports
|
||
• trader_investment_plan
|
||
│
|
||
▼
|
||
LLM Prompt (quick_think):
|
||
"Champion high-reward, high-risk opportunities.
|
||
Counter conservative and neutral analysts' points.
|
||
Highlight where caution misses critical opportunities.
|
||
Debate and persuade."
|
||
|
||
Context: trader plan + 4 reports + conservative/neutral arguments
|
||
│
|
||
▼
|
||
Output:
|
||
• risk_debate_state.aggressive_history (appended)
|
||
• risk_debate_state.current_aggressive_response
|
||
• risk_debate_state.count (incremented)
|
||
```
|
||
|
||
---
|
||
|
||
### 4.10 Conservative Debator
|
||
|
||
| | |
|
||
|---|---|
|
||
| **File** | `agents/risk_mgmt/conservative_debator.py` |
|
||
| **Factory** | `create_conservative_debator(llm)` |
|
||
| **Thinking Modality** | **Quick** (`quick_think_llm`, default `gpt-5-mini`) |
|
||
| **Tool Execution** | None — pure LLM reasoning |
|
||
|
||
**Data Flow:**
|
||
|
||
```
|
||
State Input:
|
||
• risk_debate_state.history
|
||
• risk_debate_state.current_aggressive_response
|
||
• risk_debate_state.current_neutral_response
|
||
• 4 analyst reports + trader_investment_plan
|
||
│
|
||
▼
|
||
LLM Prompt (quick_think):
|
||
"Protect assets, minimize volatility. Critically
|
||
examine high-risk elements. Counter aggressive and
|
||
neutral points. Emphasise downsides. Debate to
|
||
demonstrate strength of low-risk strategy."
|
||
│
|
||
▼
|
||
Output:
|
||
• risk_debate_state.conservative_history (appended)
|
||
• risk_debate_state.current_conservative_response
|
||
• risk_debate_state.count (incremented)
|
||
```
|
||
|
||
---
|
||
|
||
### 4.11 Neutral Debator
|
||
|
||
| | |
|
||
|---|---|
|
||
| **File** | `agents/risk_mgmt/neutral_debator.py` |
|
||
| **Factory** | `create_neutral_debator(llm)` |
|
||
| **Thinking Modality** | **Quick** (`quick_think_llm`, default `gpt-5-mini`) |
|
||
| **Tool Execution** | None — pure LLM reasoning |
|
||
|
||
**Data Flow:**
|
||
|
||
```
|
||
State Input:
|
||
• risk_debate_state.history
|
||
• risk_debate_state.current_aggressive_response
|
||
• risk_debate_state.current_conservative_response
|
||
• 4 analyst reports + trader_investment_plan
|
||
│
|
||
▼
|
||
LLM Prompt (quick_think):
|
||
"Provide balanced perspective. Challenge both
|
||
aggressive (overly optimistic) and conservative
|
||
(overly cautious). Support moderate, sustainable
|
||
strategy. Debate to show balanced view."
|
||
│
|
||
▼
|
||
Output:
|
||
• risk_debate_state.neutral_history (appended)
|
||
• risk_debate_state.current_neutral_response
|
||
• risk_debate_state.count (incremented)
|
||
```
|
||
|
||
---
|
||
|
||
### 4.12 Risk Manager
|
||
|
||
| | |
|
||
|---|---|
|
||
| **File** | `agents/managers/risk_manager.py` |
|
||
| **Factory** | `create_risk_manager(llm, memory)` |
|
||
| **Thinking Modality** | **Deep** (`deep_think_llm`, default `gpt-5.2`) |
|
||
| **Tool Execution** | None — pure LLM reasoning |
|
||
|
||
**Data Flow:**
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────┐
|
||
│ State Input: │
|
||
│ • risk_debate_state (Aggressive + Conservative + │
|
||
│ Neutral debate history) │
|
||
│ • 4 analyst reports │
|
||
│ • investment_plan (Research Manager's plan) │
|
||
│ • trader_investment_plan (Trader's refinement) │
|
||
│ • macro_regime_report │
|
||
└────────────────────────┬────────────────────────────┘
|
||
│
|
||
▼
|
||
Memory Retrieval:
|
||
memory.get_memories(situation, n_matches=2)
|
||
→ 2 past risk decisions & outcomes
|
||
│
|
||
▼
|
||
LLM Prompt (deep_think):
|
||
"Evaluate risk debate between Aggressive, Conservative,
|
||
Neutral analysts. Make clear decision: BUY / SELL / HOLD.
|
||
Account for macro regime. Learn from past mistakes.
|
||
Refine trader's plan. Provide detailed reasoning."
|
||
|
||
Context: full risk debate + trader plan + 4 reports +
|
||
macro regime + 2 memories
|
||
│
|
||
▼
|
||
Output:
|
||
• risk_debate_state.judge_decision
|
||
• final_trade_decision (the system's final answer)
|
||
```
|
||
|
||
---
|
||
|
||
### 4.13 Geopolitical Scanner
|
||
|
||
| | |
|
||
|---|---|
|
||
| **File** | `agents/scanners/geopolitical_scanner.py` |
|
||
| **Factory** | `create_geopolitical_scanner(llm)` |
|
||
| **Thinking Modality** | **Quick** (`quick_think_llm`, default `gpt-5-mini`) |
|
||
| **Tool Execution** | `run_tool_loop()` (inline, up to 5 rounds) |
|
||
|
||
**Data Flow:**
|
||
|
||
```
|
||
State Input: scan_date
|
||
│
|
||
▼
|
||
Tool calls via run_tool_loop():
|
||
|
||
1. get_topic_news("geopolitics", limit=10)
|
||
→ Fetches geopolitical news articles
|
||
Data source: yfinance / Alpha Vantage
|
||
|
||
2. get_topic_news("trade policy sanctions", limit=10)
|
||
→ Trade & sanctions news
|
||
|
||
3. get_topic_news("central bank monetary policy", limit=10)
|
||
→ Central bank signals
|
||
|
||
4. get_topic_news("energy oil commodities", limit=10)
|
||
→ Energy & commodity supply risks
|
||
|
||
(LLM decides which topics to search — up to 5 rounds)
|
||
│
|
||
▼
|
||
LLM Prompt (quick_think):
|
||
"Scan global news for risks and opportunities affecting
|
||
financial markets. Cover: major geopolitical events,
|
||
central bank signals, trade/sanctions, energy/commodity
|
||
risks. Include risk assessment table."
|
||
|
||
Context: all retrieved news articles
|
||
│
|
||
▼
|
||
Output: geopolitical_report
|
||
```
|
||
|
||
---
|
||
|
||
### 4.14 Market Movers Scanner
|
||
|
||
| | |
|
||
|---|---|
|
||
| **File** | `agents/scanners/market_movers_scanner.py` |
|
||
| **Factory** | `create_market_movers_scanner(llm)` |
|
||
| **Thinking Modality** | **Quick** (`quick_think_llm`, default `gpt-5-mini`) |
|
||
| **Tool Execution** | `run_tool_loop()` |
|
||
|
||
**Data Flow:**
|
||
|
||
```
|
||
State Input: scan_date
|
||
│
|
||
▼
|
||
Tool calls via run_tool_loop():
|
||
|
||
1. get_market_movers("day_gainers")
|
||
→ Top gaining stocks (symbol, price, change%, volume, market cap)
|
||
Data source: yfinance / Alpha Vantage
|
||
|
||
2. get_market_movers("day_losers")
|
||
→ Top losing stocks
|
||
|
||
3. get_market_movers("most_actives")
|
||
→ Highest-volume stocks
|
||
|
||
4. get_market_indices()
|
||
→ Major indices: SPY, DJI, NASDAQ, VIX, Russell 2000
|
||
(price, daily change, 52W high/low)
|
||
Data source: yfinance
|
||
│
|
||
▼
|
||
LLM Prompt (quick_think):
|
||
"Scan for unusual activity and momentum signals.
|
||
Cover: unusual movers & catalysts, volume anomalies,
|
||
index trends & breadth, sector concentration.
|
||
Include summary table."
|
||
|
||
Context: gainers + losers + most active + index data
|
||
│
|
||
▼
|
||
Output: market_movers_report
|
||
```
|
||
|
||
---
|
||
|
||
### 4.15 Sector Scanner
|
||
|
||
| | |
|
||
|---|---|
|
||
| **File** | `agents/scanners/sector_scanner.py` |
|
||
| **Factory** | `create_sector_scanner(llm)` |
|
||
| **Thinking Modality** | **Quick** (`quick_think_llm`, default `gpt-5-mini`) |
|
||
| **Tool Execution** | `run_tool_loop()` |
|
||
|
||
**Data Flow:**
|
||
|
||
```
|
||
State Input: scan_date
|
||
│
|
||
▼
|
||
Tool calls via run_tool_loop():
|
||
|
||
1. get_sector_performance()
|
||
→ All 11 GICS sectors with 1-day, 1-week, 1-month, YTD returns
|
||
Data source: yfinance (sector ETF proxies) / Alpha Vantage
|
||
│
|
||
▼
|
||
LLM Prompt (quick_think):
|
||
"Analyze sector rotation across all 11 GICS sectors.
|
||
Cover: momentum rankings, rotation signals (money flows),
|
||
defensive vs cyclical positioning, acceleration/deceleration.
|
||
Include ranked performance table."
|
||
|
||
Context: sector performance data
|
||
│
|
||
▼
|
||
Output: sector_performance_report
|
||
```
|
||
|
||
---
|
||
|
||
### 4.16 Industry Deep Dive
|
||
|
||
| | |
|
||
|---|---|
|
||
| **File** | `agents/scanners/industry_deep_dive.py` |
|
||
| **Factory** | `create_industry_deep_dive(llm)` |
|
||
| **Thinking Modality** | **Mid** (`mid_think_llm`, falls back to `quick_think_llm`) |
|
||
| **Tool Execution** | `run_tool_loop()` |
|
||
|
||
**Data Flow:**
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────┐
|
||
│ State Input: │
|
||
│ • scan_date │
|
||
│ • geopolitical_report (Phase 1) │
|
||
│ • market_movers_report (Phase 1) │
|
||
│ • sector_performance_report (Phase 1) │
|
||
└────────────────────────┬────────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────┐
|
||
│ Pre-processing (Python, no LLM): │
|
||
│ _extract_top_sectors(sector_performance_report) │
|
||
│ → Parses Markdown table from Sector Scanner │
|
||
│ → Ranks sectors by absolute 1-month move │
|
||
│ → Returns top 3 sector keys │
|
||
└────────────────────────┬────────────────────────────┘
|
||
│
|
||
▼
|
||
Tool calls via run_tool_loop():
|
||
|
||
1. get_industry_performance("technology")
|
||
→ Top companies in sector: rating, market weight,
|
||
1D/1W/1M returns
|
||
Data source: yfinance / Alpha Vantage
|
||
|
||
2. get_industry_performance("energy")
|
||
(repeated for each top sector)
|
||
|
||
3. get_industry_performance("healthcare")
|
||
(up to 3 sector calls)
|
||
|
||
4. get_topic_news("semiconductor industry", limit=10)
|
||
→ Sector-specific news for context
|
||
|
||
5. get_topic_news("renewable energy", limit=10)
|
||
(at least 2 sector-specific news searches)
|
||
│
|
||
▼
|
||
LLM Prompt (mid_think):
|
||
"Drill into the most interesting sectors from Phase 1.
|
||
MUST call tools before writing. Explain why these
|
||
industries selected. Identify top companies, catalysts,
|
||
risks. Cross-reference geopolitical events and sectors."
|
||
|
||
Context: Phase 1 reports + industry data + sector news
|
||
│
|
||
▼
|
||
Output: industry_deep_dive_report
|
||
```
|
||
|
||
---
|
||
|
||
### 4.17 Macro Synthesis
|
||
|
||
| | |
|
||
|---|---|
|
||
| **File** | `agents/scanners/macro_synthesis.py` |
|
||
| **Factory** | `create_macro_synthesis(llm)` |
|
||
| **Thinking Modality** | **Deep** (`deep_think_llm`, default `gpt-5.2`) |
|
||
| **Tool Execution** | None — pure LLM reasoning |
|
||
|
||
**Data Flow:**
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────┐
|
||
│ State Input: │
|
||
│ • geopolitical_report (Phase 1) │
|
||
│ • market_movers_report (Phase 1) │
|
||
│ • sector_performance_report (Phase 1) │
|
||
│ • industry_deep_dive_report (Phase 2) │
|
||
└────────────────────────┬────────────────────────────┘
|
||
│
|
||
▼
|
||
LLM Prompt (deep_think):
|
||
"Synthesize all reports into final investment thesis.
|
||
Output ONLY valid JSON (no markdown, no preamble).
|
||
Structure:
|
||
{
|
||
executive_summary, macro_context,
|
||
key_themes (with conviction levels),
|
||
stocks_to_investigate (8-10 picks with
|
||
ticker, sector, rationale, thesis_angle,
|
||
conviction, key_catalysts, risks),
|
||
risk_factors
|
||
}"
|
||
|
||
Context: all 4 prior reports concatenated
|
||
│
|
||
▼
|
||
Post-processing (Python, no LLM):
|
||
extract_json() → strips markdown fences / <think> blocks
|
||
│
|
||
▼
|
||
Output: macro_scan_summary (JSON string)
|
||
```
|
||
|
||
---
|
||
|
||
## 5. Tool → Data-Source Mapping
|
||
|
||
Every tool routes through `dataflows/interface.py:route_to_vendor()` which
|
||
dispatches to the configured vendor.
|
||
|
||
### Trading Tools
|
||
|
||
| Tool | Category | Default Vendor | Fallback | Returns |
|
||
|------|----------|---------------|----------|---------|
|
||
| `get_stock_data` | core_stock_apis | yfinance | Alpha Vantage | OHLCV string |
|
||
| `get_indicators` | technical_indicators | yfinance | Alpha Vantage | Indicator values |
|
||
| `get_macro_regime` | *(composed)* | yfinance | — | Regime report |
|
||
| `get_fundamentals` | fundamental_data | yfinance | Alpha Vantage | Fundamentals |
|
||
| `get_balance_sheet` | fundamental_data | yfinance | Alpha Vantage | Balance sheet |
|
||
| `get_cashflow` | fundamental_data | yfinance | Alpha Vantage | Cash flow |
|
||
| `get_income_statement` | fundamental_data | yfinance | Alpha Vantage | Income stmt |
|
||
| `get_ttm_analysis` | *(composed)* | yfinance | — | TTM metrics |
|
||
| `get_peer_comparison` | *(composed)* | yfinance | — | Peer ranking |
|
||
| `get_sector_relative` | *(composed)* | yfinance | — | Alpha report |
|
||
| `get_news` | news_data | yfinance | Alpha Vantage | News articles |
|
||
| `get_global_news` | news_data | yfinance | Alpha Vantage | Global news |
|
||
| `get_insider_transactions` | *(tool override)* | **Finnhub** | Alpha Vantage | Insider txns |
|
||
|
||
### Scanner Tools
|
||
|
||
| Tool | Category | Default Vendor | Fallback | Returns |
|
||
|------|----------|---------------|----------|---------|
|
||
| `get_market_movers` | scanner_data | yfinance | Alpha Vantage | Movers table |
|
||
| `get_market_indices` | scanner_data | yfinance | — | Index table |
|
||
| `get_sector_performance` | scanner_data | yfinance | Alpha Vantage | Sector table |
|
||
| `get_industry_performance` | scanner_data | yfinance | — | Industry table |
|
||
| `get_topic_news` | scanner_data | yfinance | — | Topic news |
|
||
| `get_earnings_calendar` | calendar_data | **Finnhub** | — | Earnings cal. |
|
||
| `get_economic_calendar` | calendar_data | **Finnhub** | — | Econ cal. |
|
||
|
||
> **Fallback rules** (ADR 011): Only 5 methods in `FALLBACK_ALLOWED` get
|
||
> cross-vendor fallback. All others fail-fast on error.
|
||
|
||
---
|
||
|
||
## 6. Memory System
|
||
|
||
The framework uses **BM25-based lexical similarity** (offline, no API calls)
|
||
to retrieve relevant past trading situations.
|
||
|
||
### Memory Instances
|
||
|
||
| Instance | Used By | Purpose |
|
||
|----------|---------|---------|
|
||
| `bull_memory` | Bull Researcher | Past bullish analyses & outcomes |
|
||
| `bear_memory` | Bear Researcher | Past bearish analyses & outcomes |
|
||
| `trader_memory` | Trader | Past trading decisions & results |
|
||
| `invest_judge_memory` | Research Manager | Past investment judgments |
|
||
| `risk_manager_memory` | Risk Manager | Past risk decisions |
|
||
|
||
### How Memory Works
|
||
|
||
```
|
||
Agent builds "current situation" string from:
|
||
• company ticker + trade date
|
||
• analyst report summaries
|
||
• debate context
|
||
│
|
||
▼
|
||
memory.get_memories(current_situation, n_matches=2)
|
||
→ BM25 tokenises situation and scores against stored documents
|
||
→ Returns top 2 matches:
|
||
{ matched_situation, recommendation, similarity_score }
|
||
│
|
||
▼
|
||
Injected into LLM prompt as "Past Reflections"
|
||
→ Agent uses past lessons to avoid repeating mistakes
|
||
```
|
||
|
||
### Memory Data Flow
|
||
|
||
```
|
||
After trading completes → outcomes stored back:
|
||
add_situations([(situation_text, recommendation_text)])
|
||
→ Appends to document store
|
||
→ Rebuilds BM25 index for future retrieval
|
||
```
|