70 KiB
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
- Thinking-Modality Overview
- Trading Pipeline Flow
- Scanner Pipeline Flow
- Per-Agent Data Flows
- 4.1 Market Analyst
- 4.2 Fundamentals Analyst
- 4.3 News Analyst
- 4.4 Social Media Analyst
- 4.5 Bull Researcher
- 4.6 Bear Researcher
- 4.7 Research Manager
- 4.8 Trader
- 4.9 Aggressive Debator
- 4.10 Conservative Debator
- 4.11 Neutral Debator
- 4.12 Risk Manager
- 4.13 Geopolitical Scanner
- 4.14 Market Movers Scanner
- 4.15 Sector Scanner
- 4.16 Industry Deep Dive
- 4.17 Macro Synthesis
- Tool → Data-Source Mapping
- Memory System
- Tool Data Formats & Sizes
- Context Window Budget
- End-to-End Token Estimates
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) │
└─────────────────────────────────────────────────────┘
Prompt Size Budget:
| Component | Data Type | Format | Avg Size | Avg Tokens |
|---|---|---|---|---|
| System prompt | Text | Instructions + indicator list | ~2.1 KB | ~525 |
get_macro_regime result |
Markdown | Tables (regime + 6 signals) | ~0.8 KB | ~200 |
get_stock_data result (30 days) |
CSV | Header + OHLCV rows | ~5 KB | ~1,250 |
get_indicators × 8 calls |
Markdown | Daily values + description | ~7.2 KB | ~1,800 |
| Total prompt | ~15–20 KB | ~3,750–5,000 |
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
Prompt Size Budget:
| Component | Data Type | Format | Avg Size | Avg Tokens |
|---|---|---|---|---|
| System prompt | Text | Sequence instructions + metric list | ~1.4 KB | ~350 |
get_ttm_analysis result |
Markdown | Tables (TTM summary + 8-quarter history) | ~1.6 KB | ~400 |
get_fundamentals result |
Markdown | Key ratios table (~15 metrics) | ~1.5 KB | ~375 |
get_peer_comparison result |
Markdown | Ranked table (~10 peers × 6 horizons) | ~1.2 KB | ~300 |
get_sector_relative result |
Markdown | Alpha table (5–6 time periods) | ~0.8 KB | ~200 |
get_balance_sheet (optional) |
CSV | Quarterly rows (up to 8) | ~2.5 KB | ~625 |
get_cashflow (optional) |
CSV | Quarterly rows (up to 8) | ~2.5 KB | ~625 |
get_income_statement (optional) |
CSV | Quarterly rows (up to 8) | ~2.5 KB | ~625 |
| Total prompt (core) | ~6.5 KB | ~1,625 | ||
| Total prompt (with optionals) | ~14 KB | ~3,500 |
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
Prompt Size Budget:
| Component | Data Type | Format | Avg Size | Avg Tokens |
|---|---|---|---|---|
| System prompt | Text | Instructions | ~0.75 KB | ~187 |
get_news result |
Markdown | Article list (≤ 20 articles) | ~7 KB | ~1,750 |
get_global_news result |
Markdown | Article list (5 articles) | ~1.75 KB | ~437 |
get_insider_transactions result |
Markdown | Transaction table (10–50 rows) | ~1.5 KB | ~375 |
| Total prompt | ~11 KB | ~2,750 |
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
Prompt Size Budget:
| Component | Data Type | Format | Avg Size | Avg Tokens |
|---|---|---|---|---|
| System prompt | Text | Instructions | ~0.85 KB | ~212 |
get_news result |
Markdown | Article list (≤ 20 articles) | ~7 KB | ~1,750 |
| Total prompt | ~8 KB | ~2,000 |
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) │
└─────────────────────────────────────────────────────┘
Prompt Size Budget:
| Component | Data Type | Format | Avg Size (Rd 1) | Avg Size (Rd 2) | Avg Tokens (Rd 2) |
|---|---|---|---|---|---|
| Prompt template | Text | f-string with instructions | ~1.2 KB | ~1.2 KB | ~300 |
| 4 analyst reports | Text | Concatenated Markdown | ~13 KB | ~13 KB | ~3,250 |
| Debate history | Text | Accumulated transcript | ~0 KB | ~6 KB | ~1,500 |
| Last Bear argument | Text | Debate response | ~0 KB | ~2 KB | ~500 |
| Memory (2 matches) | Text | Past situations + advice | ~4 KB | ~4 KB | ~1,000 |
| Total prompt | ~18 KB | ~26 KB | ~6,550 |
Prompt grows ~8 KB per debate round as history accumulates.
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)
Prompt Size Budget: Same structure as Bull Researcher (see 4.5). Round 1 ≈ 18 KB (~4,500 tokens), Round 2 ≈ 26 KB (~6,550 tokens). Grows ~8 KB per round.
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) │
└─────────────────────────────────────────────────────┘
Prompt Size Budget (after 2 debate rounds):
| Component | Data Type | Format | Avg Size | Avg Tokens |
|---|---|---|---|---|
| System prompt | Text | Instructions | ~1.2 KB | ~300 |
| 4 analyst reports | Text | Concatenated Markdown | ~13 KB | ~3,250 |
| Full debate transcript | Text | Bull + Bear history (2 rounds) | ~20 KB | ~5,000 |
| Macro regime report | Markdown | Regime + signals table | ~0.8 KB | ~200 |
| Memory (2 matches) | Text | Past decisions + outcomes | ~4 KB | ~1,000 |
| Total prompt | ~39 KB | ~9,750 |
This is the largest single-prompt agent in the trading pipeline. With 3 debate rounds, prompt can reach ~50 KB (~12,500 tokens).
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"
Prompt Size Budget:
| Component | Data Type | Format | Avg Size | Avg Tokens |
|---|---|---|---|---|
| System message | Text | Instructions + memory | ~0.6 KB | ~150 |
| Investment plan | Text | Research Manager output | ~3 KB | ~750 |
| 4 analyst reports | Text | Concatenated Markdown | ~13 KB | ~3,250 |
| Memory (2 matches) | Text | Past decisions + outcomes | ~4 KB | ~1,000 |
| Total prompt | ~21 KB | ~5,150 |
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)
Prompt Size Budget:
| Component | Data Type | Format | Avg Size (Rd 1) | Avg Size (Rd 2) | Avg Tokens (Rd 2) |
|---|---|---|---|---|---|
| Prompt template | Text | f-string with instructions | ~1.2 KB | ~1.2 KB | ~300 |
| 4 analyst reports | Text | Concatenated Markdown | ~13 KB | ~13 KB | ~3,250 |
| Trader investment plan | Text | Decision + reasoning | ~3 KB | ~3 KB | ~750 |
| Risk debate history | Text | Accumulated transcript | ~0 KB | ~10 KB | ~2,500 |
| Conservative/Neutral args | Text | Debate responses | ~0 KB | ~4 KB | ~1,000 |
| Total prompt | ~17 KB | ~31 KB | ~7,800 |
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. Emphasize 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)
Prompt Size Budget: Same structure as Aggressive Debator (see 4.9). Round 1 ≈ 17 KB (~4,250 tokens), Round 2 ≈ 31 KB (~7,800 tokens).
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)
Prompt Size Budget: Same structure as Aggressive Debator (see 4.9). Round 1 ≈ 17 KB (~4,250 tokens), Round 2 ≈ 31 KB (~7,800 tokens).
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)
Prompt Size Budget (after 2 risk-debate rounds):
| Component | Data Type | Format | Avg Size | Avg Tokens |
|---|---|---|---|---|
| System prompt | Text | Instructions | ~1.3 KB | ~325 |
| 4 analyst reports | Text | Concatenated Markdown | ~13 KB | ~3,250 |
| Trader investment plan | Text | Decision + reasoning | ~3 KB | ~750 |
| Full risk debate transcript | Text | Aggressive + Conservative + Neutral (2 rds) | ~30 KB | ~7,500 |
| Macro regime report | Markdown | Regime + signals table | ~0.8 KB | ~200 |
| Memory (2 matches) | Text | Past risk decisions + outcomes | ~4 KB | ~1,000 |
| Total prompt | ~52 KB | ~13,025 |
Largest prompt in the entire framework. With 3 risk-debate rounds, this can reach ~70 KB (~17,500 tokens).
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
Prompt Size Budget:
| Component | Data Type | Format | Avg Size | Avg Tokens |
|---|---|---|---|---|
| System prompt | Text | Instructions | ~0.6 KB | ~150 |
get_topic_news × 3–4 calls |
Markdown | Article lists (10 articles each) | ~8 KB | ~2,000 |
| Total prompt | ~9 KB | ~2,150 |
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
Prompt Size Budget:
| Component | Data Type | Format | Avg Size | Avg Tokens |
|---|---|---|---|---|
| System prompt | Text | Instructions | ~0.6 KB | ~150 |
get_market_movers × 3 calls |
Markdown | Tables (15 stocks each) | ~4.5 KB | ~1,125 |
get_market_indices result |
Markdown | Table (5 indices) | ~1 KB | ~250 |
| Total prompt | ~6 KB | ~1,525 |
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
Prompt Size Budget:
| Component | Data Type | Format | Avg Size | Avg Tokens |
|---|---|---|---|---|
| System prompt | Text | Instructions | ~0.5 KB | ~125 |
get_sector_performance result |
Markdown | Table (11 sectors × 4 horizons) | ~0.9 KB | ~220 |
| Total prompt | ~1.4 KB | ~345 |
Smallest prompt of any scanner agent.
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
Prompt Size Budget:
| Component | Data Type | Format | Avg Size | Avg Tokens |
|---|---|---|---|---|
| System prompt | Text | Instructions + sector list | ~1 KB | ~250 |
| Phase 1 context (3 reports) | Text | Concatenated Markdown | ~6 KB | ~1,500 |
get_industry_performance × 3 |
Markdown | Tables (10–15 companies each) | ~7.5 KB | ~1,875 |
get_topic_news × 2 |
Markdown | Article lists (10 articles each) | ~5 KB | ~1,250 |
| Total prompt | ~20 KB | ~4,875 |
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)
Prompt Size Budget:
| Component | Data Type | Format | Avg Size | Avg Tokens |
|---|---|---|---|---|
| System prompt | Text | Instructions + JSON schema | ~1.3 KB | ~325 |
| Geopolitical report (Phase 1) | Text | Markdown report | ~3 KB | ~750 |
| Market movers report (Phase 1) | Text | Markdown report | ~3 KB | ~750 |
| Sector performance report (Phase 1) | Text | Markdown report | ~2 KB | ~500 |
| Industry deep dive report (Phase 2) | Text | Markdown report | ~8 KB | ~2,000 |
| Total prompt | ~17 KB | ~4,325 |
Output: Valid JSON (~3–5 KB, ~750–1,250 tokens).
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_ALLOWEDget 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
7. Tool Data Formats & Sizes
All tools return strings to the LLM. The table below shows the format, typical size, and any truncation limits for each tool.
Token estimate rule of thumb: 1 token ≈ 4 characters for English text.
Trading Tools
| Tool | Return Format | Typical Size | Tokens | Items | Truncation / Limits |
|---|---|---|---|---|---|
get_stock_data |
CSV (header + OHLCV rows) | 5–20 KB | 1,250–5,000 | 30–250 rows | None; all requested days returned |
get_indicators |
Markdown (daily values + description) | ~0.9 KB per indicator | ~225 | 30 daily values | 30-day lookback (configurable) |
get_macro_regime |
Markdown (regime table + 6 signal rows) | ~0.8 KB | ~200 | 1 regime + 6 signals | Fixed signal set |
get_fundamentals |
Markdown (key ratios table) | ~1.5 KB | ~375 | ~15 metrics | None |
get_ttm_analysis |
Markdown (TTM summary + 8-quarter table) | ~1.6 KB | ~400 | 15 metrics + 8 quarters | Last 8 quarters |
get_balance_sheet |
CSV (quarterly columns) | ~2.5 KB | ~625 | Up to 8 quarters | Last 8 quarters |
get_income_statement |
CSV (quarterly columns) | ~2.5 KB | ~625 | Up to 8 quarters | Last 8 quarters |
get_cashflow |
CSV (quarterly columns) | ~2.5 KB | ~625 | Up to 8 quarters | Last 8 quarters |
get_peer_comparison |
Markdown (ranked table) | ~1.2 KB | ~300 | ~10 peers | Top 10 sector peers |
get_sector_relative |
Markdown (alpha table) | ~0.8 KB | ~200 | 5–6 time periods | Fixed periods |
get_news |
Markdown (article list) | ~7 KB | ~1,750 | ≤ 20 articles | First 20 from API, filtered by date |
get_global_news |
Markdown (article list) | ~1.75 KB | ~437 | 5 articles (default) | Configurable limit; deduplicated |
get_insider_transactions |
Markdown (transaction table) | ~1.5 KB | ~375 | 10–50 transactions | API-dependent |
Scanner Tools
| Tool | Return Format | Typical Size | Tokens | Items | Truncation / Limits |
|---|---|---|---|---|---|
get_market_movers |
Markdown (table) | ~1.5 KB per category | ~375 | 15 stocks | Hard limit: top 15 |
get_market_indices |
Markdown (table) | ~1 KB | ~250 | 5 indices | Fixed set (SPY, DJI, NASDAQ, VIX, RUT) |
get_sector_performance |
Markdown (table) | ~0.9 KB | ~220 | 11 sectors × 4 horizons | Fixed 11 GICS sectors |
get_industry_performance |
Markdown (table) | ~2.5 KB | ~625 | 10–15 companies | Top companies by market weight |
get_topic_news |
Markdown (article list) | ~2.5 KB | ~625 | 10 articles (default) | Configurable limit |
get_earnings_calendar |
Markdown (table) | ~3 KB | ~750 | 20–50+ events | All events in date range |
get_economic_calendar |
Markdown (table) | ~2.5 KB | ~625 | 5–15 events | All events in date range |
Non-Tool Data Injected into Prompts
| Data | Format | Avg Size | Tokens | Notes |
|---|---|---|---|---|
| Memory match (× 2) | Text (situation + recommendation) | ~2 KB each | ~500 each | BM25 retrieval; injected as "Past Reflections" |
| Debate history (per round) | Text (accumulated transcript) | ~3–4 KB per turn | ~750–1,000 | Grows linearly with debate rounds |
| Analyst report (each) | Text (Markdown) | ~3 KB | ~750 | Output from analyst agents |
| Macro regime report | Markdown (tables) | ~0.8 KB | ~200 | Shared across multiple agents |
8. Context Window Budget
This section compares each agent's estimated prompt size against the context windows of popular models to identify potential overflow risks.
Model Context Windows (Reference)
| Model | Context Window | Input Limit (approx) | Notes |
|---|---|---|---|
| gpt-4o-mini | 128K tokens | ~100K usable | Default quick-think candidate |
| gpt-4o | 128K tokens | ~100K usable | Alternative quick/mid |
| gpt-5-mini | 128K tokens | ~100K usable | Default quick_think_llm |
| gpt-5.2 | 128K tokens | ~100K usable | Default deep_think_llm |
| claude-3.5-sonnet | 200K tokens | ~180K usable | Anthropic option |
| claude-4-sonnet | 200K tokens | ~180K usable | Anthropic option |
| gemini-2.5-pro | 1M tokens | ~900K usable | Google option |
| deepseek-r1 | 128K tokens | ~100K usable | OpenRouter / Ollama option |
| llama-3.1-70b | 128K tokens | ~100K usable | Ollama local option |
| mistral-large | 128K tokens | ~100K usable | OpenRouter option |
Per-Agent Prompt Size vs Context Budget
| # | Agent | Tier | Avg Prompt | Peak Prompt† | % of 128K | Risk |
|---|---|---|---|---|---|---|
| 1 | Market Analyst | Quick | ~5,000 tok | ~6,000 tok | 4–5% | ✅ Safe |
| 2 | Fundamentals Analyst | Quick | ~1,600 tok | ~3,500 tok | 1–3% | ✅ Safe |
| 3 | News Analyst | Quick | ~2,750 tok | ~3,200 tok | 2–3% | ✅ Safe |
| 4 | Social Media Analyst | Quick | ~2,000 tok | ~2,500 tok | 1–2% | ✅ Safe |
| 5 | Bull Researcher (Rd 2) | Mid | ~6,550 tok | ~10,000 tok | 5–8% | ✅ Safe |
| 6 | Bear Researcher (Rd 2) | Mid | ~6,550 tok | ~10,000 tok | 5–8% | ✅ Safe |
| 7 | Research Manager | Deep | ~9,750 tok | ~15,000 tok | 8–12% | ✅ Safe |
| 8 | Trader | Mid | ~5,150 tok | ~6,500 tok | 4–5% | ✅ Safe |
| 9 | Aggressive Debator (Rd 2) | Quick | ~7,800 tok | ~14,000 tok | 6–11% | ✅ Safe |
| 10 | Conservative Debator (Rd 2) | Quick | ~7,800 tok | ~14,000 tok | 6–11% | ✅ Safe |
| 11 | Neutral Debator (Rd 2) | Quick | ~7,800 tok | ~14,000 tok | 6–11% | ✅ Safe |
| 12 | Risk Manager | Deep | ~13,000 tok | ~17,500 tok | 10–14% | ✅ Safe |
| 13 | Geopolitical Scanner | Quick | ~2,150 tok | ~3,000 tok | 2% | ✅ Safe |
| 14 | Market Movers Scanner | Quick | ~1,525 tok | ~2,000 tok | 1–2% | ✅ Safe |
| 15 | Sector Scanner | Quick | ~345 tok | ~500 tok | <1% | ✅ Safe |
| 16 | Industry Deep Dive | Mid | ~4,875 tok | ~7,000 tok | 4–5% | ✅ Safe |
| 17 | Macro Synthesis | Deep | ~4,325 tok | ~6,500 tok | 3–5% | ✅ Safe |
†Peak Prompt = estimate with
max_debate_rounds=3or maximum optional tool calls. All agents are well within the 128K context window.
When to Watch Context Limits
Even though individual agents fit comfortably, be aware of these scenarios:
| Scenario | Estimated Total | Risk |
|---|---|---|
| Default config (2 debate rounds) | Max single prompt ≈ 17.5K tokens | ✅ No risk |
max_debate_rounds=5 |
Risk Manager prompt ≈ 30K tokens | ✅ Low risk |
max_debate_rounds=10 |
Risk Manager prompt ≈ 55K tokens | ⚠️ Monitor |
| Small context model (8K window) | Risk Manager default already 13K | ❌ Will overflow |
| Ollama local (small model, 4K ctx) | Most debate agents exceed 4K | ❌ Will overflow |
Recommendation: For local Ollama models with small context windows (e.g., 4K–8K), set
max_debate_rounds=1andmax_risk_discuss_rounds=1.
9. End-to-End Token Estimates
Trading Pipeline (Single Company Analysis)
Phase Calls Avg Tokens (per call) Subtotal
─────────────────────────────────────────────────────────────────────────
1. ANALYST PHASE (parallel)
Market Analyst 1 ~5,000 ~5,000
Fundamentals Analyst 1 ~1,600–3,500 ~2,500
News Analyst 1 ~2,750 ~2,750
Social Media Analyst 1 ~2,000 ~2,000
Phase 1: ~12,250
2. INVESTMENT DEBATE (2 rounds)
Bull Researcher 2 ~4,500 → ~6,550 ~11,050
Bear Researcher 2 ~4,500 → ~6,550 ~11,050
Phase 2: ~22,100
3. RESEARCH MANAGER
Research Manager 1 ~9,750 ~9,750
Phase 3: ~9,750
4. TRADER
Trader 1 ~5,150 ~5,150
Phase 4: ~5,150
5. RISK DEBATE (2 rounds × 3 agents)
Aggressive Debator 2 ~4,250 → ~7,800 ~12,050
Conservative Debator 2 ~4,250 → ~7,800 ~12,050
Neutral Debator 2 ~4,250 → ~7,800 ~12,050
Phase 5: ~36,150
6. RISK MANAGER
Risk Manager 1 ~13,000 ~13,000
Phase 6: ~13,000
═══════════════════════════════════════════════════════════════════════════
TOTAL INPUT TOKENS (single company): ~98,400
═══════════════════════════════════════════════════════════════════════════
Each agent also produces output tokens (~500–3,000 per call). Total output across all agents ≈ 15,000–25,000 tokens. Grand total (input + output) ≈ 115,000–125,000 tokens per company.
Scanner Pipeline (Market-Wide Scan)
Phase Calls Avg Tokens (per call) Subtotal
─────────────────────────────────────────────────────────────────────────
1. PHASE 1 SCANNERS (parallel)
Geopolitical Scanner 1 ~2,150 ~2,150
Market Movers Scanner 1 ~1,525 ~1,525
Sector Scanner 1 ~345 ~345
Phase 1: ~4,020
2. PHASE 2
Industry Deep Dive 1 ~4,875 ~4,875
Phase 2: ~4,875
3. PHASE 3
Macro Synthesis 1 ~4,325 ~4,325
Phase 3: ~4,325
═══════════════════════════════════════════════════════════════════════════
TOTAL INPUT TOKENS (market scan): ~13,220
═══════════════════════════════════════════════════════════════════════════
Scanner output tokens ≈ 5,000–8,000 additional. Grand total (input + output) ≈ 18,000–21,000 tokens per scan.
Full Pipeline (Scan → Per-Ticker Deep Dives)
When running the pipeline command (scan + per-ticker analysis for top picks):
Scanner pipeline: ~13,220 input tokens
+ N company analyses (N = 8–10 picks): ~98,400 × N input tokens
───────────────────────────────────────────────────────────────────
Example (10 companies): ~997,220 input tokens
≈ 1.0M total tokens (input + output)
Key Observations
-
No automatic truncation: The framework concatenates all tool output and debate history into prompts without truncation. Context usage grows linearly with debate rounds.
-
Debate history is the main driver: In a 2-round debate, history adds ~8 KB per round per debater. The Risk Manager sees all three debaters' accumulated history.
-
All prompts fit 128K models: Even the largest prompt (Risk Manager at peak) uses only ~14% of a 128K context window.
-
Small-context models are at risk: Models with ≤ 8K context windows cannot accommodate debate agents beyond round 1. Use
max_debate_rounds=1for such models. -
Cost optimization: The scanner pipeline uses ~13K tokens total — roughly 7× cheaper than a single company analysis.