TradingAgents/docs/api/trading-graph.md

458 lines
11 KiB
Markdown

# TradingGraph API Reference
The `TradingAgentsGraph` class is the main entry point for the TradingAgents framework. It orchestrates all agents, manages state, and coordinates the analysis workflow.
## Class: TradingAgentsGraph
Location: `tradingagents/graph/trading_graph.py`
### Constructor
```python
TradingAgentsGraph(
selected_analysts: List[str] = ["market", "social", "news", "fundamentals"],
debug: bool = False,
config: Dict[str, Any] = None
)
```
#### Parameters
- **selected_analysts** (List[str], optional): List of analyst types to include in analysis
- Default: `["market", "social", "news", "fundamentals"]`
- Available: `"market"`, `"social"`, `"news"`, `"fundamentals"`
- Example: `["market", "fundamentals"]` for technical and fundamental analysis only
- **debug** (bool, optional): Enable debug mode with verbose logging
- Default: `False`
- When `True`: Prints detailed execution traces and intermediate states
- **config** (Dict[str, Any], optional): Configuration dictionary
- Default: `None` (uses `DEFAULT_CONFIG`)
- See [Configuration Reference](../guides/configuration.md) for all options
#### Returns
- Instance of `TradingAgentsGraph`
#### Example
```python
from tradingagents.graph.trading_graph import TradingAgentsGraph
from tradingagents.default_config import DEFAULT_CONFIG
# Basic initialization
ta = TradingAgentsGraph()
# With custom analysts
ta = TradingAgentsGraph(
selected_analysts=["market", "fundamentals"],
debug=True
)
# With custom configuration
config = DEFAULT_CONFIG.copy()
config["llm_provider"] = "anthropic"
config["deep_think_llm"] = "claude-sonnet-4-20250514"
ta = TradingAgentsGraph(config=config)
```
### Methods
#### propagate()
Run the complete trading analysis workflow for a company on a specific date.
```python
propagate(
company_name: str,
trade_date: str
) -> Tuple[Dict[str, Any], Dict[str, Any]]
```
##### Parameters
- **company_name** (str): Ticker symbol of the company to analyze
- Example: `"NVDA"`, `"AAPL"`, `"TSLA"`
- Must be a valid US stock ticker
- **trade_date** (str): Date for analysis in YYYY-MM-DD format
- Example: `"2024-05-10"`
- Must be a valid trading day (not weekend or holiday)
##### Returns
Tuple of two dictionaries:
1. **Final State** (Dict[str, Any]): Complete agent state after analysis
- Contains all analyst reports, debate outcomes, risk assessments
- Useful for debugging and detailed inspection
2. **Trading Decision** (Dict[str, Any]): The final trading recommendation
- `action`: `"BUY"`, `"SELL"`, or `"HOLD"`
- `confidence_score`: Float between 0.0 and 1.0
- `reasoning`: Detailed explanation of the decision
- `position_size`: Recommended position size (if applicable)
- `risk_assessment`: Risk evaluation summary
##### Example
```python
ta = TradingAgentsGraph(debug=True)
# Run analysis
final_state, decision = ta.propagate("NVDA", "2024-05-10")
# Access decision
print(f"Action: {decision['action']}")
print(f"Confidence: {decision['confidence_score']:.2%}")
print(f"Reasoning: {decision['reasoning']}")
# Access detailed state
print(f"Analyst Reports: {final_state['analyst_reports']}")
print(f"Research Synthesis: {final_state['research_synthesis']}")
```
##### Raises
- **ValueError**: Invalid ticker or date format
- **LLMRateLimitError**: LLM API rate limit exceeded
- **DataUnavailableError**: Required data not available for the ticker/date
- **APIError**: Generic API error from LLM or data provider
## Configuration
### Default Configuration
The default configuration is defined in `tradingagents/default_config.py`:
```python
DEFAULT_CONFIG = {
# Directories
"project_dir": "<auto-detected>",
"results_dir": "./results",
"data_cache_dir": "./dataflows/data_cache",
# LLM settings
"llm_provider": "openai",
"deep_think_llm": "o4-mini",
"quick_think_llm": "gpt-4o-mini",
"backend_url": "https://api.openai.com/v1",
# Workflow settings
"max_debate_rounds": 1,
"max_risk_discuss_rounds": 1,
"max_recur_limit": 100,
# Data vendors
"data_vendors": {
"core_stock_apis": "yfinance",
"technical_indicators": "yfinance",
"fundamental_data": "alpha_vantage",
"news_data": "alpha_vantage"
}
}
```
### Customizing Configuration
```python
from tradingagents.default_config import DEFAULT_CONFIG
config = DEFAULT_CONFIG.copy()
# Change LLM provider
config["llm_provider"] = "anthropic"
config["deep_think_llm"] = "claude-sonnet-4-20250514"
# Increase debate rounds
config["max_debate_rounds"] = 2
# Change data vendors
config["data_vendors"]["news_data"] = "google"
# Initialize with custom config
ta = TradingAgentsGraph(config=config)
```
## Workflow Stages
The `propagate()` method executes these stages:
### 1. Data Collection
All selected analysts collect relevant data in parallel:
- **Market Analyst**: Stock prices, technical indicators
- **Fundamentals Analyst**: Financial statements, ratios
- **Sentiment Analyst**: Social media sentiment
- **News Analyst**: News articles, events
### 2. Analyst Reports
Each analyst generates a specialized report:
```python
state.analyst_reports = {
"market": "Technical analysis shows bullish MACD crossover...",
"fundamentals": "Strong balance sheet with P/E ratio of 35...",
"sentiment": "Positive social sentiment with score 0.75...",
"news": "Recent product launch expected to boost revenue..."
}
```
### 3. Research Debate
Bull and Bear researchers debate the analyst findings:
```python
# Round 1
bull_researcher: "Strong fundamentals support upside potential..."
bear_researcher: "High valuation creates downside risk..."
# Round 2 (if configured)
bull_researcher: "Growth prospects justify premium valuation..."
bear_researcher: "Market volatility increases uncertainty..."
# Synthesis
research_manager: "Balanced view: Bullish bias with risk management..."
```
### 4. Trading Decision
Trader agent synthesizes all inputs and makes a decision:
```python
decision = {
"action": "BUY",
"confidence_score": 0.75,
"reasoning": "Strong fundamentals and positive momentum outweigh valuation concerns...",
"position_size": 0.05 # 5% of portfolio
}
```
### 5. Risk Validation
Risk management team evaluates the proposal:
```python
risk_assessment = {
"approved": True,
"risk_score": 0.3, # Low to medium risk
"recommendations": [
"Set stop-loss at -5%",
"Monitor volatility",
"Review position after earnings"
]
}
```
### 6. Final Decision
Portfolio manager approves or rejects:
```python
final_decision = {
"approved": True,
"action": "BUY",
"confidence_score": 0.75,
"execution_details": {
"position_size": 0.05,
"stop_loss": -0.05,
"take_profit": 0.15
}
}
```
## State Management
The graph maintains state through the `AgentState` class:
```python
@dataclass
class AgentState:
ticker: str
date: str
analyst_reports: Dict[str, str]
research_synthesis: str
trading_decision: Dict[str, Any]
risk_assessment: Dict[str, Any]
final_decision: Dict[str, Any]
```
Location: `tradingagents/agents/utils/agent_states.py`
## Memory System
The graph uses `FinancialSituationMemory` for context retention:
```python
from tradingagents.agents.utils.memory import FinancialSituationMemory
memory = FinancialSituationMemory(
persist_directory="./memory_cache"
)
# Store analysis
memory.add_situation(
ticker="NVDA",
date="2024-05-10",
analysis=state
)
# Retrieve similar past analyses
similar = memory.search_similar(
query="NVDA technical analysis",
k=5
)
```
## Error Handling
### Handling Rate Limits
```python
from tradingagents.utils.exceptions import LLMRateLimitError
import time
def run_with_retry(ta, ticker, date, max_retries=3):
for attempt in range(max_retries):
try:
return ta.propagate(ticker, date)
except LLMRateLimitError as e:
if attempt < max_retries - 1:
wait_time = e.retry_after or 60
print(f"Rate limit hit. Waiting {wait_time}s...")
time.sleep(wait_time)
else:
raise
```
### Handling Missing Data
```python
from tradingagents.utils.exceptions import DataUnavailableError
try:
state, decision = ta.propagate("INVALID", "2024-05-10")
except DataUnavailableError as e:
print(f"Data not available: {e}")
# Fall back to alternative ticker or date
```
## Performance Considerations
### Execution Time
Typical execution times (single ticker):
- **1 debate round**: 30-60 seconds
- **2 debate rounds**: 60-120 seconds
- **3 debate rounds**: 120-180 seconds
Factors affecting speed:
- Number of selected analysts
- Number of debate rounds
- LLM provider and model choice
- Data vendor API latency
### Cost Optimization
Estimated costs per analysis:
| Configuration | LLM Calls | Cost (USD) |
|---------------|-----------|------------|
| Minimal (1 round, 2 analysts) | ~10-15 | $0.05-0.10 |
| Standard (1 round, 4 analysts) | ~20-25 | $0.10-0.20 |
| Deep (2 rounds, 4 analysts) | ~35-45 | $0.20-0.40 |
Cost reduction strategies:
- Use `gpt-4o-mini` instead of `o4-mini` for testing
- Reduce debate rounds
- Select only necessary analysts
- Enable caching
### Parallel Execution
Analyze multiple tickers in parallel:
```python
import asyncio
from concurrent.futures import ThreadPoolExecutor
tickers = ["NVDA", "AAPL", "MSFT", "TSLA"]
date = "2024-05-10"
def analyze_ticker(ticker):
ta = TradingAgentsGraph()
return ta.propagate(ticker, date)
with ThreadPoolExecutor(max_workers=4) as executor:
results = list(executor.map(analyze_ticker, tickers))
```
## Examples
### Basic Usage
```python
from tradingagents.graph.trading_graph import TradingAgentsGraph
ta = TradingAgentsGraph(debug=True)
state, decision = ta.propagate("NVDA", "2024-05-10")
print(f"Decision: {decision['action']}")
print(f"Confidence: {decision['confidence_score']:.2%}")
```
### Custom Analysts
```python
# Only technical and fundamental analysis
ta = TradingAgentsGraph(
selected_analysts=["market", "fundamentals"],
debug=True
)
state, decision = ta.propagate("AAPL", "2024-05-10")
```
### Multiple LLM Providers
```python
# Use different models for deep vs. quick thinking
config = DEFAULT_CONFIG.copy()
config["llm_provider"] = "openrouter"
config["deep_think_llm"] = "anthropic/claude-sonnet-4.5"
config["quick_think_llm"] = "openai/gpt-4o-mini"
ta = TradingAgentsGraph(config=config)
state, decision = ta.propagate("TSLA", "2024-05-10")
```
### Batch Analysis
```python
tickers = ["NVDA", "AAPL", "MSFT"]
date = "2024-05-10"
results = {}
ta = TradingAgentsGraph()
for ticker in tickers:
state, decision = ta.propagate(ticker, date)
results[ticker] = decision
# Compare decisions
for ticker, decision in results.items():
print(f"{ticker}: {decision['action']} ({decision['confidence_score']:.2%})")
```
## See Also
- [Multi-Agent System Architecture](../architecture/multi-agent-system.md)
- [Agents API Reference](agents.md)
- [Configuration Guide](../guides/configuration.md)
- [Adding New Analyst](../guides/adding-new-analyst.md)