5.5 KiB
5.5 KiB
TradingAgents Framework - Project Knowledge
Project Overview
Multi-agent LLM trading framework using LangGraph for financial analysis and decision making.
Development Environment
Conda Environment: tradingagents
Before starting any development work, activate the conda environment:
conda activate tradingagents
Architecture
- Agent Factory Pattern:
create_X(llm)→ closure pattern - 3-Tier LLM System:
- Quick thinking (fast responses)
- Mid thinking (balanced analysis)
- Deep thinking (complex reasoning)
- Data Vendor Routing: yfinance (primary), Alpha Vantage (fallback)
- Graph-Based Workflows: LangGraph for agent coordination
Key Directories
tradingagents/agents/- Agent implementationstradingagents/graph/- Workflow graphs and setuptradingagents/dataflows/- Data access layercli/- Command-line interface
Agent Flow (Existing Trading Analysis)
- Analysts (parallel): Fundamentals, Market, News, Social Media
- Bull/Bear Debate
- Research Manager
- Trader
- Risk Debate
- Risk Judge
Scanner Flow (New Market-Wide Analysis)
START ──┬── Geopolitical Scanner (quick_think) ──┐
├── Market Movers Scanner (quick_think) ──┼── Industry Deep Dive (mid_think) ── Macro Synthesis (deep_think) ── END
└── Sector Scanner (quick_think) ─────────┘
- Phase 1: Parallel execution of 3 scanners
- Phase 2: Industry Deep Dive cross-references all outputs
- Phase 3: Macro Synthesis produces top-10 watchlist
Data Vendors
- yfinance (primary, free): Screener(), Sector(), Industry(), index tickers
- Alpha Vantage (alternative, API key required): TOP_GAINERS_LOSERS endpoint only (fallback for market movers)
LLM Providers
OpenAI, Anthropic, Google, xAI, OpenRouter, Ollama
CLI Entry Point
cli/main.py with Typer:
analyze(per-ticker analysis)scan(new, market-wide scan)
Configuration
tradingagents/default_config.py:
- LLM tiers configuration
- Vendor routing
- Debate rounds settings
- All values overridable via
TRADINGAGENTS_<KEY>env vars (see.env.example)
Patterns to Follow
- Agent creation (trading):
tradingagents/agents/analysts/news_analyst.py - Agent creation (scanner):
tradingagents/agents/scanners/geopolitical_scanner.py - Tools:
tradingagents/agents/utils/news_data_tools.py - Scanner tools:
tradingagents/agents/utils/scanner_tools.py - Graph setup (trading):
tradingagents/graph/setup.py - Graph setup (scanner):
tradingagents/graph/scanner_setup.py - Inline tool loop:
tradingagents/agents/utils/tool_runner.py
Critical Patterns (see docs/agent/decisions/008-lessons-learned.md for full details)
- Tool execution: Trading graph uses
ToolNodein graph. Scanner agents userun_tool_loop()inline. Ifbind_tools()is used, there MUST be a tool execution path. - yfinance DataFrames:
top_companieshas ticker as INDEX, not column. Always check.indexand.columns. - yfinance Sector/Industry:
Sector.overviewhas NO performance data. Use ETF proxies for performance. - Vendor fallback: Functions inside
route_to_vendormust RAISE on failure, not embed errors in return values. Catch(AlphaVantageError, ConnectionError, TimeoutError), not justRateLimitError. - LangGraph parallel writes: Any state field written by parallel nodes MUST have a reducer (
Annotated[str, reducer_fn]). - Ollama remote host: Never hardcode
localhost:11434. Use configuredbase_url. - .env loading:
load_dotenv()runs at module level indefault_config.py— import-order-independent. Check actual env var values when debugging auth. - Rate limiter locks: Never hold a lock during
sleep()or IO. Release, sleep, re-acquire. - Config fallback keys:
llm_providerandbackend_urlmust always exist at top level —scanner_graph.pyandtrading_graph.pyuse them as fallbacks.
Agentic Memory (docs/agent/)
Agent workflows use the docs/agent/ scaffold for structured memory:
docs/agent/CURRENT_STATE.md— Live state tracker (milestone, progress, blockers). Read at session start.docs/agent/decisions/— Architecture decision records (ADR-style, numbered001-...)docs/agent/plans/— Implementation plans with checkbox progress trackingdocs/agent/logs/— Agent run logsdocs/agent/templates/— Commit, PR, and decision templates
Before starting work, always read docs/agent/CURRENT_STATE.md. Before committing, update it.
LLM Configuration
Per-tier provider overrides in tradingagents/default_config.py:
- Each tier (
quick_think,mid_think,deep_think) can have its own_llm_providerand_backend_url - Falls back to top-level
llm_providerandbackend_urlwhen per-tier values are None - All config values overridable via
TRADINGAGENTS_<KEY>env vars - Keys for LLM providers:
.envfile (e.g.,OPENROUTER_API_KEY,ALPHA_VANTAGE_API_KEY)
Env Var Override Convention
# Pattern: TRADINGAGENTS_<UPPERCASE_KEY>=value
TRADINGAGENTS_LLM_PROVIDER=openrouter
TRADINGAGENTS_DEEP_THINK_LLM=deepseek/deepseek-r1-0528
TRADINGAGENTS_MAX_DEBATE_ROUNDS=3
TRADINGAGENTS_VENDOR_SCANNER_DATA=alpha_vantage
Empty or unset vars preserve the hardcoded default. None-default fields (like mid_think_llm) stay None when unset, preserving fallback semantics.
Running the Scanner
conda activate tradingagents
python -m cli.main scan --date 2026-03-17
Running Tests
conda activate tradingagents
pytest tests/ -v