Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fda4f664e8 | ||
|
|
718df34932 | ||
|
|
43aa9c5d09 | ||
|
|
26c5ba5a78 | ||
|
|
78ea029a0b | ||
|
|
ee3d499894 | ||
|
|
7abff0f354 | ||
|
|
b575bd0941 | ||
|
|
b8f712b170 | ||
|
|
52284ce13c | ||
|
|
11804f88ff | ||
|
|
1e86e74314 | ||
|
|
c2f897fc67 | ||
|
|
ed32081f57 | ||
|
|
2af7ef3d79 | ||
|
|
383deb72aa | ||
|
|
7eaf4d995f | ||
|
|
da84ef43aa | ||
|
|
90b23e72f5 | ||
|
|
417b09712c | ||
|
|
570644d939 | ||
|
|
9647359246 | ||
|
|
99789f9cd1 | ||
|
|
a879868396 | ||
|
|
0013415378 | ||
|
|
0fdfd35867 | ||
|
|
e994e56c23 | ||
|
|
47176ba8a2 | ||
|
|
5f1c9c43cf |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -6,3 +6,4 @@ src/
|
|||||||
eval_results/
|
eval_results/
|
||||||
eval_data/
|
eval_data/
|
||||||
*.egg-info/
|
*.egg-info/
|
||||||
|
.env
|
||||||
|
|||||||
1
.python-version
Normal file
1
.python-version
Normal file
@@ -0,0 +1 @@
|
|||||||
|
3.10
|
||||||
31
README.md
31
README.md
@@ -11,6 +11,18 @@
|
|||||||
<a href="https://github.com/TauricResearch/" target="_blank"><img alt="Community" src="https://img.shields.io/badge/Join_GitHub_Community-TauricResearch-14C290?logo=discourse"/></a>
|
<a href="https://github.com/TauricResearch/" target="_blank"><img alt="Community" src="https://img.shields.io/badge/Join_GitHub_Community-TauricResearch-14C290?logo=discourse"/></a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div align="center">
|
||||||
|
<!-- Keep these links. Translations will automatically update with the README. -->
|
||||||
|
<a href="https://www.readme-i18n.com/TauricResearch/TradingAgents?lang=de">Deutsch</a> |
|
||||||
|
<a href="https://www.readme-i18n.com/TauricResearch/TradingAgents?lang=es">Español</a> |
|
||||||
|
<a href="https://www.readme-i18n.com/TauricResearch/TradingAgents?lang=fr">français</a> |
|
||||||
|
<a href="https://www.readme-i18n.com/TauricResearch/TradingAgents?lang=ja">日本語</a> |
|
||||||
|
<a href="https://www.readme-i18n.com/TauricResearch/TradingAgents?lang=ko">한국어</a> |
|
||||||
|
<a href="https://www.readme-i18n.com/TauricResearch/TradingAgents?lang=pt">Português</a> |
|
||||||
|
<a href="https://www.readme-i18n.com/TauricResearch/TradingAgents?lang=ru">Русский</a> |
|
||||||
|
<a href="https://www.readme-i18n.com/TauricResearch/TradingAgents?lang=zh">中文</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# TradingAgents: Multi-Agents LLM Financial Trading Framework
|
# TradingAgents: Multi-Agents LLM Financial Trading Framework
|
||||||
@@ -19,6 +31,16 @@
|
|||||||
>
|
>
|
||||||
> So we decided to fully open-source the framework. Looking forward to building impactful projects with you!
|
> So we decided to fully open-source the framework. Looking forward to building impactful projects with you!
|
||||||
|
|
||||||
|
<div align="center">
|
||||||
|
<a href="https://www.star-history.com/#TauricResearch/TradingAgents&Date">
|
||||||
|
<picture>
|
||||||
|
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=TauricResearch/TradingAgents&type=Date&theme=dark" />
|
||||||
|
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=TauricResearch/TradingAgents&type=Date" />
|
||||||
|
<img alt="TradingAgents Star History" src="https://api.star-history.com/svg?repos=TauricResearch/TradingAgents&type=Date" style="width: 80%; height: auto;" />
|
||||||
|
</picture>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div align="center">
|
<div align="center">
|
||||||
|
|
||||||
🚀 [TradingAgents](#tradingagents-framework) | ⚡ [Installation & CLI](#installation-and-cli) | 🎬 [Demo](https://www.youtube.com/watch?v=90gr5lwjIho) | 📦 [Package Usage](#tradingagents-package) | 🤝 [Contributing](#contributing) | 📄 [Citation](#citation)
|
🚀 [TradingAgents](#tradingagents-framework) | ⚡ [Installation & CLI](#installation-and-cli) | 🎬 [Demo](https://www.youtube.com/watch?v=90gr5lwjIho) | 📦 [Package Usage](#tradingagents-package) | 🤝 [Contributing](#contributing) | 📄 [Citation](#citation)
|
||||||
@@ -58,7 +80,7 @@ Our framework decomposes complex trading tasks into specialized roles. This ensu
|
|||||||
- Composes reports from the analysts and researchers to make informed trading decisions. It determines the timing and magnitude of trades based on comprehensive market insights.
|
- Composes reports from the analysts and researchers to make informed trading decisions. It determines the timing and magnitude of trades based on comprehensive market insights.
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="assets/risk.png" width="70%" style="display: inline-block; margin: 0 2%;">
|
<img src="assets/trader.png" width="70%" style="display: inline-block; margin: 0 2%;">
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
### Risk Management and Portfolio Manager
|
### Risk Management and Portfolio Manager
|
||||||
@@ -66,7 +88,7 @@ Our framework decomposes complex trading tasks into specialized roles. This ensu
|
|||||||
- The Portfolio Manager approves/rejects the transaction proposal. If approved, the order will be sent to the simulated exchange and executed.
|
- The Portfolio Manager approves/rejects the transaction proposal. If approved, the order will be sent to the simulated exchange and executed.
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="assets/trader.png" width="70%" style="display: inline-block; margin: 0 2%;">
|
<img src="assets/risk.png" width="70%" style="display: inline-block; margin: 0 2%;">
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
## Installation and CLI
|
## Installation and CLI
|
||||||
@@ -92,7 +114,7 @@ pip install -r requirements.txt
|
|||||||
|
|
||||||
### Required APIs
|
### Required APIs
|
||||||
|
|
||||||
You will also need the FinnHub API and EODHD API for financial data. All of our code is implemented with the free tier.
|
You will also need the FinnHub API for financial data. All of our code is implemented with the free tier.
|
||||||
```bash
|
```bash
|
||||||
export FINNHUB_API_KEY=$YOUR_FINNHUB_API_KEY
|
export FINNHUB_API_KEY=$YOUR_FINNHUB_API_KEY
|
||||||
```
|
```
|
||||||
@@ -136,8 +158,9 @@ To use TradingAgents inside your code, you can import the `tradingagents` module
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
from tradingagents.graph.trading_graph import TradingAgentsGraph
|
from tradingagents.graph.trading_graph import TradingAgentsGraph
|
||||||
|
from tradingagents.default_config import DEFAULT_CONFIG
|
||||||
|
|
||||||
ta = TradingAgentsGraph(debug=True, config=config)
|
ta = TradingAgentsGraph(debug=True, config=DEFAULT_CONFIG.copy())
|
||||||
|
|
||||||
# forward propagate
|
# forward propagate
|
||||||
_, decision = ta.propagate("NVDA", "2024-05-10")
|
_, decision = ta.propagate("NVDA", "2024-05-10")
|
||||||
|
|||||||
112
cli/main.py
112
cli/main.py
@@ -1,6 +1,8 @@
|
|||||||
from typing import Optional
|
from typing import Optional
|
||||||
import datetime
|
import datetime
|
||||||
import typer
|
import typer
|
||||||
|
from pathlib import Path
|
||||||
|
from functools import wraps
|
||||||
from rich.console import Console
|
from rich.console import Console
|
||||||
from rich.panel import Panel
|
from rich.panel import Panel
|
||||||
from rich.spinner import Spinner
|
from rich.spinner import Spinner
|
||||||
@@ -295,10 +297,27 @@ def update_display(layout, spinner_text=None):
|
|||||||
|
|
||||||
# Add regular messages
|
# Add regular messages
|
||||||
for timestamp, msg_type, content in message_buffer.messages:
|
for timestamp, msg_type, content in message_buffer.messages:
|
||||||
|
# Convert content to string if it's not already
|
||||||
|
content_str = content
|
||||||
|
if isinstance(content, list):
|
||||||
|
# Handle list of content blocks (Anthropic format)
|
||||||
|
text_parts = []
|
||||||
|
for item in content:
|
||||||
|
if isinstance(item, dict):
|
||||||
|
if item.get('type') == 'text':
|
||||||
|
text_parts.append(item.get('text', ''))
|
||||||
|
elif item.get('type') == 'tool_use':
|
||||||
|
text_parts.append(f"[Tool: {item.get('name', 'unknown')}]")
|
||||||
|
else:
|
||||||
|
text_parts.append(str(item))
|
||||||
|
content_str = ' '.join(text_parts)
|
||||||
|
elif not isinstance(content_str, str):
|
||||||
|
content_str = str(content)
|
||||||
|
|
||||||
# Truncate message content if too long
|
# Truncate message content if too long
|
||||||
if isinstance(content, str) and len(content) > 200:
|
if len(content_str) > 200:
|
||||||
content = content[:197] + "..."
|
content_str = content_str[:197] + "..."
|
||||||
all_messages.append((timestamp, msg_type, content))
|
all_messages.append((timestamp, msg_type, content_str))
|
||||||
|
|
||||||
# Sort by timestamp
|
# Sort by timestamp
|
||||||
all_messages.sort(key=lambda x: x[0])
|
all_messages.sort(key=lambda x: x[0])
|
||||||
@@ -444,20 +463,30 @@ def get_user_selections():
|
|||||||
)
|
)
|
||||||
selected_research_depth = select_research_depth()
|
selected_research_depth = select_research_depth()
|
||||||
|
|
||||||
# Step 5: Thinking agents
|
# Step 5: OpenAI backend
|
||||||
console.print(
|
console.print(
|
||||||
create_question_box(
|
create_question_box(
|
||||||
"Step 5: Thinking Agents", "Select your thinking agents for analysis"
|
"Step 5: OpenAI backend", "Select which service to talk to"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
selected_shallow_thinker = select_shallow_thinking_agent()
|
selected_llm_provider, backend_url = select_llm_provider()
|
||||||
selected_deep_thinker = select_deep_thinking_agent()
|
|
||||||
|
# Step 6: Thinking agents
|
||||||
|
console.print(
|
||||||
|
create_question_box(
|
||||||
|
"Step 6: Thinking Agents", "Select your thinking agents for analysis"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
selected_shallow_thinker = select_shallow_thinking_agent(selected_llm_provider)
|
||||||
|
selected_deep_thinker = select_deep_thinking_agent(selected_llm_provider)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"ticker": selected_ticker,
|
"ticker": selected_ticker,
|
||||||
"analysis_date": analysis_date,
|
"analysis_date": analysis_date,
|
||||||
"analysts": selected_analysts,
|
"analysts": selected_analysts,
|
||||||
"research_depth": selected_research_depth,
|
"research_depth": selected_research_depth,
|
||||||
|
"llm_provider": selected_llm_provider.lower(),
|
||||||
|
"backend_url": backend_url,
|
||||||
"shallow_thinker": selected_shallow_thinker,
|
"shallow_thinker": selected_shallow_thinker,
|
||||||
"deep_thinker": selected_deep_thinker,
|
"deep_thinker": selected_deep_thinker,
|
||||||
}
|
}
|
||||||
@@ -683,6 +712,24 @@ def update_research_team_status(status):
|
|||||||
for agent in research_team:
|
for agent in research_team:
|
||||||
message_buffer.update_agent_status(agent, status)
|
message_buffer.update_agent_status(agent, status)
|
||||||
|
|
||||||
|
def extract_content_string(content):
|
||||||
|
"""Extract string content from various message formats."""
|
||||||
|
if isinstance(content, str):
|
||||||
|
return content
|
||||||
|
elif isinstance(content, list):
|
||||||
|
# Handle Anthropic's list format
|
||||||
|
text_parts = []
|
||||||
|
for item in content:
|
||||||
|
if isinstance(item, dict):
|
||||||
|
if item.get('type') == 'text':
|
||||||
|
text_parts.append(item.get('text', ''))
|
||||||
|
elif item.get('type') == 'tool_use':
|
||||||
|
text_parts.append(f"[Tool: {item.get('name', 'unknown')}]")
|
||||||
|
else:
|
||||||
|
text_parts.append(str(item))
|
||||||
|
return ' '.join(text_parts)
|
||||||
|
else:
|
||||||
|
return str(content)
|
||||||
|
|
||||||
def run_analysis():
|
def run_analysis():
|
||||||
# First get all user selections
|
# First get all user selections
|
||||||
@@ -694,12 +741,61 @@ def run_analysis():
|
|||||||
config["max_risk_discuss_rounds"] = selections["research_depth"]
|
config["max_risk_discuss_rounds"] = selections["research_depth"]
|
||||||
config["quick_think_llm"] = selections["shallow_thinker"]
|
config["quick_think_llm"] = selections["shallow_thinker"]
|
||||||
config["deep_think_llm"] = selections["deep_thinker"]
|
config["deep_think_llm"] = selections["deep_thinker"]
|
||||||
|
config["backend_url"] = selections["backend_url"]
|
||||||
|
config["llm_provider"] = selections["llm_provider"].lower()
|
||||||
|
|
||||||
# Initialize the graph
|
# Initialize the graph
|
||||||
graph = TradingAgentsGraph(
|
graph = TradingAgentsGraph(
|
||||||
[analyst.value for analyst in selections["analysts"]], config=config, debug=True
|
[analyst.value for analyst in selections["analysts"]], config=config, debug=True
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Create result directory
|
||||||
|
results_dir = Path(config["results_dir"]) / selections["ticker"] / selections["analysis_date"]
|
||||||
|
results_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
report_dir = results_dir / "reports"
|
||||||
|
report_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
log_file = results_dir / "message_tool.log"
|
||||||
|
log_file.touch(exist_ok=True)
|
||||||
|
|
||||||
|
def save_message_decorator(obj, func_name):
|
||||||
|
func = getattr(obj, func_name)
|
||||||
|
@wraps(func)
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
func(*args, **kwargs)
|
||||||
|
timestamp, message_type, content = obj.messages[-1]
|
||||||
|
content = content.replace("\n", " ") # Replace newlines with spaces
|
||||||
|
with open(log_file, "a") as f:
|
||||||
|
f.write(f"{timestamp} [{message_type}] {content}\n")
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
def save_tool_call_decorator(obj, func_name):
|
||||||
|
func = getattr(obj, func_name)
|
||||||
|
@wraps(func)
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
func(*args, **kwargs)
|
||||||
|
timestamp, tool_name, args = obj.tool_calls[-1]
|
||||||
|
args_str = ", ".join(f"{k}={v}" for k, v in args.items())
|
||||||
|
with open(log_file, "a") as f:
|
||||||
|
f.write(f"{timestamp} [Tool Call] {tool_name}({args_str})\n")
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
def save_report_section_decorator(obj, func_name):
|
||||||
|
func = getattr(obj, func_name)
|
||||||
|
@wraps(func)
|
||||||
|
def wrapper(section_name, content):
|
||||||
|
func(section_name, content)
|
||||||
|
if section_name in obj.report_sections and obj.report_sections[section_name] is not None:
|
||||||
|
content = obj.report_sections[section_name]
|
||||||
|
if content:
|
||||||
|
file_name = f"{section_name}.md"
|
||||||
|
with open(report_dir / file_name, "w") as f:
|
||||||
|
f.write(content)
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
message_buffer.add_message = save_message_decorator(message_buffer, "add_message")
|
||||||
|
message_buffer.add_tool_call = save_tool_call_decorator(message_buffer, "add_tool_call")
|
||||||
|
message_buffer.update_report_section = save_report_section_decorator(message_buffer, "update_report_section")
|
||||||
|
|
||||||
# Now start the display layout
|
# Now start the display layout
|
||||||
layout = create_layout()
|
layout = create_layout()
|
||||||
|
|
||||||
@@ -754,7 +850,7 @@ def run_analysis():
|
|||||||
|
|
||||||
# Extract message content and type
|
# Extract message content and type
|
||||||
if hasattr(last_message, "content"):
|
if hasattr(last_message, "content"):
|
||||||
content = last_message.content
|
content = extract_content_string(last_message.content) # Use the helper function
|
||||||
msg_type = "Reasoning"
|
msg_type = "Reasoning"
|
||||||
else:
|
else:
|
||||||
content = str(last_message)
|
content = str(last_message)
|
||||||
|
|||||||
119
cli/utils.py
119
cli/utils.py
@@ -122,22 +122,44 @@ def select_research_depth() -> int:
|
|||||||
return choice
|
return choice
|
||||||
|
|
||||||
|
|
||||||
def select_shallow_thinking_agent() -> str:
|
def select_shallow_thinking_agent(provider) -> str:
|
||||||
"""Select shallow thinking llm engine using an interactive selection."""
|
"""Select shallow thinking llm engine using an interactive selection."""
|
||||||
|
|
||||||
# Define shallow thinking llm engine options with their corresponding model names
|
# Define shallow thinking llm engine options with their corresponding model names
|
||||||
SHALLOW_AGENT_OPTIONS = [
|
SHALLOW_AGENT_OPTIONS = {
|
||||||
("GPT-4o-mini - Fast and efficient for quick tasks", "gpt-4o-mini"),
|
"openai": [
|
||||||
("GPT-4.1-nano - Ultra-lightweight model for basic operations", "gpt-4.1-nano"),
|
("GPT-4o-mini - Fast and efficient for quick tasks", "gpt-4o-mini"),
|
||||||
("GPT-4.1-mini - Compact model with good performance", "gpt-4.1-mini"),
|
("GPT-4.1-nano - Ultra-lightweight model for basic operations", "gpt-4.1-nano"),
|
||||||
("GPT-4o - Standard model with solid capabilities", "gpt-4o"),
|
("GPT-4.1-mini - Compact model with good performance", "gpt-4.1-mini"),
|
||||||
]
|
("GPT-4o - Standard model with solid capabilities", "gpt-4o"),
|
||||||
|
],
|
||||||
|
"anthropic": [
|
||||||
|
("Claude Haiku 3.5 - Fast inference and standard capabilities", "claude-3-5-haiku-latest"),
|
||||||
|
("Claude Sonnet 3.5 - Highly capable standard model", "claude-3-5-sonnet-latest"),
|
||||||
|
("Claude Sonnet 3.7 - Exceptional hybrid reasoning and agentic capabilities", "claude-3-7-sonnet-latest"),
|
||||||
|
("Claude Sonnet 4 - High performance and excellent reasoning", "claude-sonnet-4-0"),
|
||||||
|
],
|
||||||
|
"google": [
|
||||||
|
("Gemini 2.0 Flash-Lite - Cost efficiency and low latency", "gemini-2.0-flash-lite"),
|
||||||
|
("Gemini 2.0 Flash - Next generation features, speed, and thinking", "gemini-2.0-flash"),
|
||||||
|
("Gemini 2.5 Flash - Adaptive thinking, cost efficiency", "gemini-2.5-flash-preview-05-20"),
|
||||||
|
],
|
||||||
|
"openrouter": [
|
||||||
|
("Meta: Llama 4 Scout", "meta-llama/llama-4-scout:free"),
|
||||||
|
("Meta: Llama 3.3 8B Instruct - A lightweight and ultra-fast variant of Llama 3.3 70B", "meta-llama/llama-3.3-8b-instruct:free"),
|
||||||
|
("google/gemini-2.0-flash-exp:free - Gemini Flash 2.0 offers a significantly faster time to first token", "google/gemini-2.0-flash-exp:free"),
|
||||||
|
],
|
||||||
|
"ollama": [
|
||||||
|
("llama3.1 local", "llama3.1"),
|
||||||
|
("llama3.2 local", "llama3.2"),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
choice = questionary.select(
|
choice = questionary.select(
|
||||||
"Select Your [Quick-Thinking LLM Engine]:",
|
"Select Your [Quick-Thinking LLM Engine]:",
|
||||||
choices=[
|
choices=[
|
||||||
questionary.Choice(display, value=value)
|
questionary.Choice(display, value=value)
|
||||||
for display, value in SHALLOW_AGENT_OPTIONS
|
for display, value in SHALLOW_AGENT_OPTIONS[provider.lower()]
|
||||||
],
|
],
|
||||||
instruction="\n- Use arrow keys to navigate\n- Press Enter to select",
|
instruction="\n- Use arrow keys to navigate\n- Press Enter to select",
|
||||||
style=questionary.Style(
|
style=questionary.Style(
|
||||||
@@ -158,25 +180,48 @@ def select_shallow_thinking_agent() -> str:
|
|||||||
return choice
|
return choice
|
||||||
|
|
||||||
|
|
||||||
def select_deep_thinking_agent() -> str:
|
def select_deep_thinking_agent(provider) -> str:
|
||||||
"""Select deep thinking llm engine using an interactive selection."""
|
"""Select deep thinking llm engine using an interactive selection."""
|
||||||
|
|
||||||
# Define deep thinking llm engine options with their corresponding model names
|
# Define deep thinking llm engine options with their corresponding model names
|
||||||
DEEP_AGENT_OPTIONS = [
|
DEEP_AGENT_OPTIONS = {
|
||||||
("GPT-4.1-nano - Ultra-lightweight model for basic operations", "gpt-4.1-nano"),
|
"openai": [
|
||||||
("GPT-4.1-mini - Compact model with good performance", "gpt-4.1-mini"),
|
("GPT-4.1-nano - Ultra-lightweight model for basic operations", "gpt-4.1-nano"),
|
||||||
("GPT-4o - Standard model with solid capabilities", "gpt-4o"),
|
("GPT-4.1-mini - Compact model with good performance", "gpt-4.1-mini"),
|
||||||
("o4-mini - Specialized reasoning model (compact)", "o4-mini"),
|
("GPT-4o - Standard model with solid capabilities", "gpt-4o"),
|
||||||
("o3-mini - Advanced reasoning model (lightweight)", "o3-mini"),
|
("o4-mini - Specialized reasoning model (compact)", "o4-mini"),
|
||||||
("o3 - Full advanced reasoning model", "o3"),
|
("o3-mini - Advanced reasoning model (lightweight)", "o3-mini"),
|
||||||
("o1 - Premier reasoning and problem-solving model", "o1"),
|
("o3 - Full advanced reasoning model", "o3"),
|
||||||
]
|
("o1 - Premier reasoning and problem-solving model", "o1"),
|
||||||
|
],
|
||||||
|
"anthropic": [
|
||||||
|
("Claude Haiku 3.5 - Fast inference and standard capabilities", "claude-3-5-haiku-latest"),
|
||||||
|
("Claude Sonnet 3.5 - Highly capable standard model", "claude-3-5-sonnet-latest"),
|
||||||
|
("Claude Sonnet 3.7 - Exceptional hybrid reasoning and agentic capabilities", "claude-3-7-sonnet-latest"),
|
||||||
|
("Claude Sonnet 4 - High performance and excellent reasoning", "claude-sonnet-4-0"),
|
||||||
|
("Claude Opus 4 - Most powerful Anthropic model", " claude-opus-4-0"),
|
||||||
|
],
|
||||||
|
"google": [
|
||||||
|
("Gemini 2.0 Flash-Lite - Cost efficiency and low latency", "gemini-2.0-flash-lite"),
|
||||||
|
("Gemini 2.0 Flash - Next generation features, speed, and thinking", "gemini-2.0-flash"),
|
||||||
|
("Gemini 2.5 Flash - Adaptive thinking, cost efficiency", "gemini-2.5-flash-preview-05-20"),
|
||||||
|
("Gemini 2.5 Pro", "gemini-2.5-pro-preview-06-05"),
|
||||||
|
],
|
||||||
|
"openrouter": [
|
||||||
|
("DeepSeek V3 - a 685B-parameter, mixture-of-experts model", "deepseek/deepseek-chat-v3-0324:free"),
|
||||||
|
("Deepseek - latest iteration of the flagship chat model family from the DeepSeek team.", "deepseek/deepseek-chat-v3-0324:free"),
|
||||||
|
],
|
||||||
|
"ollama": [
|
||||||
|
("llama3.1 local", "llama3.1"),
|
||||||
|
("qwen3", "qwen3"),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
choice = questionary.select(
|
choice = questionary.select(
|
||||||
"Select Your [Deep-Thinking LLM Engine]:",
|
"Select Your [Deep-Thinking LLM Engine]:",
|
||||||
choices=[
|
choices=[
|
||||||
questionary.Choice(display, value=value)
|
questionary.Choice(display, value=value)
|
||||||
for display, value in DEEP_AGENT_OPTIONS
|
for display, value in DEEP_AGENT_OPTIONS[provider.lower()]
|
||||||
],
|
],
|
||||||
instruction="\n- Use arrow keys to navigate\n- Press Enter to select",
|
instruction="\n- Use arrow keys to navigate\n- Press Enter to select",
|
||||||
style=questionary.Style(
|
style=questionary.Style(
|
||||||
@@ -193,3 +238,39 @@ def select_deep_thinking_agent() -> str:
|
|||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
return choice
|
return choice
|
||||||
|
|
||||||
|
def select_llm_provider() -> tuple[str, str]:
|
||||||
|
"""Select the OpenAI api url using interactive selection."""
|
||||||
|
# Define OpenAI api options with their corresponding endpoints
|
||||||
|
BASE_URLS = [
|
||||||
|
("OpenAI", "https://api.openai.com/v1"),
|
||||||
|
("Anthropic", "https://api.anthropic.com/"),
|
||||||
|
("Google", "https://generativelanguage.googleapis.com/v1"),
|
||||||
|
("Openrouter", "https://openrouter.ai/api/v1"),
|
||||||
|
("Ollama", "http://localhost:11434/v1"),
|
||||||
|
]
|
||||||
|
|
||||||
|
choice = questionary.select(
|
||||||
|
"Select your LLM Provider:",
|
||||||
|
choices=[
|
||||||
|
questionary.Choice(display, value=(display, value))
|
||||||
|
for display, value in BASE_URLS
|
||||||
|
],
|
||||||
|
instruction="\n- Use arrow keys to navigate\n- Press Enter to select",
|
||||||
|
style=questionary.Style(
|
||||||
|
[
|
||||||
|
("selected", "fg:magenta noinherit"),
|
||||||
|
("highlighted", "fg:magenta noinherit"),
|
||||||
|
("pointer", "fg:magenta noinherit"),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
).ask()
|
||||||
|
|
||||||
|
if choice is None:
|
||||||
|
console.print("\n[red]no OpenAI backend selected. Exiting...[/red]")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
display_name, url = choice
|
||||||
|
print(f"You selected: {display_name}\tURL: {url}")
|
||||||
|
|
||||||
|
return display_name, url
|
||||||
|
|||||||
447
index.html
447
index.html
@@ -1,447 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="description" content="TradingAgents: Multi-Agents LLM Financial Trading Framework">
|
|
||||||
<meta name="keywords" content="TradingAgents, LLM, Financial Trading, Multi-Agent Systems, Financial Markets, AI Trading">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
||||||
<title>TradingAgents: Multi-Agents LLM Financial Trading Framework</title>
|
|
||||||
|
|
||||||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-PYVRSFMDRL"></script>
|
|
||||||
<script>
|
|
||||||
window.dataLayer = window.dataLayer || [];
|
|
||||||
function gtag() { dataLayer.push(arguments); }
|
|
||||||
gtag('js', new Date());
|
|
||||||
gtag('config', 'G-PYVRSFMDRL');
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<link href="https://fonts.googleapis.com/css?family=Google+Sans|Noto+Sans|Castoro" rel="stylesheet">
|
|
||||||
<link rel="stylesheet" href="./static/css/bulma.min.css">
|
|
||||||
<link rel="stylesheet" href="./static/css/bulma-carousel.min.css">
|
|
||||||
<link rel="stylesheet" href="./static/css/bulma-slider.min.css">
|
|
||||||
<link rel="stylesheet" href="./static/css/fontawesome.all.min.css">
|
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/jpswalsh/academicons@1/css/academicons.min.css">
|
|
||||||
<link rel="stylesheet" href="./static/css/index.css">
|
|
||||||
<link rel="icon" href="./static/images/TradingAgents.png">
|
|
||||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
|
|
||||||
<script defer src="./static/js/fontawesome.all.min.js"></script>
|
|
||||||
<script src="./static/js/bulma-carousel.min.js"></script>
|
|
||||||
<script src="./static/js/bulma-slider.min.js"></script>
|
|
||||||
<script src="./static/js/index.js"></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<nav class="navbar" role="navigation" aria-label="main navigation">
|
|
||||||
<div class="navbar-brand">
|
|
||||||
<a role="button" class="navbar-burger" aria-label="menu" aria-expanded="false">
|
|
||||||
<span aria-hidden="true"></span>
|
|
||||||
<span aria-hidden="true"></span>
|
|
||||||
<span aria-hidden="true"></span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="navbar-menu">
|
|
||||||
<div class="navbar-start" style="flex-grow: 1; justify-content: center;">
|
|
||||||
<a class="navbar-item" href="https://yijia-xiao.github.io/">
|
|
||||||
<span class="icon">
|
|
||||||
<i class="fas fa-home"></i>
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
<div class="navbar-item has-dropdown is-hoverable">
|
|
||||||
<a class="navbar-link">More Research</a>
|
|
||||||
<div class="navbar-dropdown">
|
|
||||||
<a class="navbar-item" href="https://arxiv.org/abs/2408.11363">ProteinGPT</a>
|
|
||||||
<a class="navbar-item" href="https://arxiv.org/abs/2310.02469">PrivacyMind</a>
|
|
||||||
<a class="navbar-item" href="https://arxiv.org/abs/2412.20138">TradingAgents</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<section class="hero">
|
|
||||||
<div class="hero-body">
|
|
||||||
<div class="container is-max-desktop">
|
|
||||||
<div class="columns is-centered">
|
|
||||||
<div class="column has-text-centered">
|
|
||||||
<h1 class="title is-1 publication-title">TradingAgents: Multi-Agents LLM Financial Trading Framework</h1>
|
|
||||||
<div class="is-size-5 publication-authors">
|
|
||||||
<a href="https://yijia-xiao.github.io/" target="_blank" rel="noopener noreferrer"><span class="author-block">Yijia Xiao<sup>1</sup>,</span></a>
|
|
||||||
<span class="author-block">Edward Sun<sup>1</sup>,</span>
|
|
||||||
<span class="author-block">Di Luo<sup>1,2</sup>,</span>
|
|
||||||
<span class="author-block">Wei Wang<sup>1</sup></span>
|
|
||||||
</div>
|
|
||||||
<div class="is-size-5 publication-authors">
|
|
||||||
<span class="author-block"><sup>1</sup>University of California, Los Angeles,</span>
|
|
||||||
<span class="author-block"><sup>2</sup>Massachusetts Institute of Technology</span>
|
|
||||||
</div>
|
|
||||||
<div class="column has-text-centered">
|
|
||||||
<div class="publication-links">
|
|
||||||
<span class="link-block"><a href="https://arxiv.org/abs/2412.20138" class="external-link button is-normal is-rounded is-dark"><span class="icon"><i class="fas fa-file-pdf"></i></span><span>Paper</span></a></span>
|
|
||||||
<span class="link-block"><a href="https://github.com/TradingAgents-AI" class="external-link button is-normal is-rounded is-dark"><span class="icon"><i class="fab fa-github"></i></span><span>Code</span></a></span>
|
|
||||||
<span class="link-block"><a href="#citation-ref" class="external-link button is-normal is-rounded is-dark"><span class="icon"><i class="fas fa-quote-right"></i></span><span>Citation</span></a></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="section">
|
|
||||||
<div class="container is-max-desktop">
|
|
||||||
<div class="columns is-centered has-text-centered">
|
|
||||||
<div class="column is-four-fifths">
|
|
||||||
<h2 class="title is-3">Abstract</h2>
|
|
||||||
<div class="content has-text-justified">
|
|
||||||
<p>We introduce <strong>TradingAgents</strong>, a novel stock trading framework inspired by trading firms, utilizing multiple LLM-powered agents with specialized roles such as fundamental, sentiment, and technical analysts, as well as traders with diverse risk profiles. The system features Bull and Bear researchers evaluating market conditions, a risk management team overseeing exposure, and traders integrating insights from debates and historical data to make informed decisions. This collaborative, dynamic environment enhances trading performance, as demonstrated by our comprehensive experiments showing significant improvements in cumulative returns, Sharpe ratio, and maximum drawdown compared to baseline models. Our results highlight the effectiveness of multi-agent LLM frameworks in financial trading.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="section">
|
|
||||||
<div class="container is-max-desktop">
|
|
||||||
<div class="columns is-centered">
|
|
||||||
<div class="column is-full-width">
|
|
||||||
<h2 class="title is-3">TradingAgents: Overview</h2>
|
|
||||||
<div class="content has-text-justified">
|
|
||||||
<p><strong>TradingAgents</strong> leverages a multi-agent framework to simulate a professional trading firm with distinct roles: fundamental, sentiment, and technical analysts; researchers; traders; and risk managers. These agents collaborate through structured communication and debates, enhancing decision-making and optimizing trading strategies.</p>
|
|
||||||
<figure class="image">
|
|
||||||
<img src="./static/images/schema.png" alt="TradingAgents Overall Framework Organization">
|
|
||||||
<figcaption class="has-text-centered"><strong>Figure 1:</strong> TradingAgents Overall Framework Organization.<br><strong>I. Analysts Team</strong>: Four analysts concurrently gather relevant market information.<br><strong>II. Research Team</strong>: The team discusses and evaluates the collected data.<br><strong>III. Trader</strong>: Based on the researchers' analysis, the trader makes the trading decision.<br><strong>IV. Risk Management Team</strong>: Risk guardians assess the decision against current market conditions to mitigate risks.<br><strong>V. Fund Manager</strong>: The fund manager approves and executes the trade.</em></figcaption>
|
|
||||||
</figure>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="section">
|
|
||||||
<div class="container is-max-desktop">
|
|
||||||
<div class="columns is-centered">
|
|
||||||
<div class="column is-full-width">
|
|
||||||
<h2 class="title is-3">TradingAgents: Role Specialization</h2>
|
|
||||||
<div class="content has-text-justified">
|
|
||||||
<p>Assigning specific roles to LLM agents allows complex trading objectives to be broken down into manageable tasks. Inspired by trading firms, <strong>TradingAgents</strong> features seven distinct roles: Fundamentals Analyst, Sentiment Analyst, News Analyst, Technical Analyst, Researcher, Trader, and Risk Manager. Each agent is equipped with specialized tools and constraints tailored to their function, ensuring comprehensive market analysis and informed decision-making.</p>
|
|
||||||
|
|
||||||
<h3 class="title is-4">Analyst Team</h3>
|
|
||||||
<div class="content has-text-justified">
|
|
||||||
<p>The Analyst Team gathers and analyzes market data across various domains:</p>
|
|
||||||
<ul>
|
|
||||||
<li><strong>Fundamental Analysts:</strong> Assess company fundamentals to identify undervalued or overvalued stocks.</li>
|
|
||||||
<li><strong>Sentiment Analysts:</strong> Analyze social media and public sentiment to gauge market mood.</li>
|
|
||||||
<li><strong>News Analysts:</strong> Evaluate news and macroeconomic indicators to predict market movements.</li>
|
|
||||||
<li><strong>Technical Analysts:</strong> Use technical indicators to forecast price trends and trading opportunities.</li>
|
|
||||||
</ul>
|
|
||||||
<p>Combined, their insights provide a holistic market view, feeding into the Researcher Team for further evaluation.</p>
|
|
||||||
|
|
||||||
<figure class="image">
|
|
||||||
<img src="./static/images/Analyst.png" alt="TradingAgents Analyst Team" style="width: 65%;">
|
|
||||||
<figcaption class="has-text-centered"><strong>Figure 2:</strong> TradingAgents Analyst Team</figcaption>
|
|
||||||
</figure>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h3 class="title is-4">Researcher Team</h3>
|
|
||||||
<div class="content has-text-justified">
|
|
||||||
<p>The Researcher Team critically evaluates analyst data through a dialectical process involving bullish and bearish perspectives. This debate ensures balanced analysis, identifying both opportunities and risks to inform trading strategies.</p>
|
|
||||||
|
|
||||||
<div class="columns">
|
|
||||||
<div class="column">
|
|
||||||
<figure class="image">
|
|
||||||
<img src="./static/images/Researcher.png" alt="TradingAgents Researcher Team">
|
|
||||||
<figcaption class="has-text-centered"><strong>Figure 3:</strong> TradingAgents Researcher Team</figcaption>
|
|
||||||
</figure>
|
|
||||||
</div>
|
|
||||||
<div class="column">
|
|
||||||
<figure class="image">
|
|
||||||
<img src="./static/images/Trader.png" alt="TradingAgents Trader Decision-Making Process">
|
|
||||||
<figcaption class="has-text-centered"><strong>Figure 4:</strong> TradingAgents Trader Decision-Making Process</figcaption>
|
|
||||||
</figure>
|
|
||||||
</div>
|
|
||||||
<div class="column">
|
|
||||||
<figure class="image">
|
|
||||||
<img src="./static/images/RiskMGMT.png" alt="TradingAgents Risk Management Team Workflow">
|
|
||||||
<figcaption class="has-text-centered"><strong>Figure 5:</strong> TradingAgents Risk Management Workflow</figcaption>
|
|
||||||
</figure>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li><strong>Bullish Researchers:</strong> Highlight positive market indicators and growth potential.</li>
|
|
||||||
<li><strong>Bearish Researchers:</strong> Focus on risks and negative market signals.</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<p>This process ensures a balanced understanding of market conditions, aiding Trader Agents in making informed decisions.</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h3 class="title is-4">Trader Agents</h3>
|
|
||||||
<div class="content has-text-justified">
|
|
||||||
<p>Trader Agents execute decisions based on comprehensive analyses. They evaluate insights from analysts and researchers to determine optimal trading actions, balancing returns and risks in a dynamic market environment.</p>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li>Assessing analyst and researcher recommendations.</li>
|
|
||||||
<li>Determining trade timing and size.</li>
|
|
||||||
<li>Executing buy/sell orders.</li>
|
|
||||||
<li>Adjusting portfolios in response to market changes.</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<p>Precision and strategic thinking are essential for their role in maximizing performance.</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h3 class="title is-4">Risk Management Team</h3>
|
|
||||||
<div class="content has-text-justified">
|
|
||||||
<p>The Risk Management Team oversees the firm's exposure to market risks, ensuring trading activities stay within predefined limits.</p>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li>Assessing market volatility and liquidity.</li>
|
|
||||||
<li>Implementing risk mitigation strategies.</li>
|
|
||||||
<li>Advising Trader Agents on risk exposures.</li>
|
|
||||||
<li>Aligning portfolio with risk tolerance.</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<p>They ensure financial stability and safeguard assets through effective risk control.</p>
|
|
||||||
|
|
||||||
<p>All agents utilize the ReAct prompting framework, facilitating a collaborative and dynamic decision-making process reflective of real-world trading systems.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="section">
|
|
||||||
<div class="container is-max-desktop">
|
|
||||||
<div class="columns is-centered">
|
|
||||||
<div class="column is-full-width">
|
|
||||||
<h2 class="title is-3">TradingAgents: Agent Workflow</h2>
|
|
||||||
<div class="content has-text-justified">
|
|
||||||
<h3 class="title is-4">Communication Protocol</h3>
|
|
||||||
<p>To enhance communication efficiency, <strong>TradingAgents</strong> employs a structured protocol that combines clear, structured outputs with natural language dialogue. This approach minimizes information loss and maintains context over long interactions, ensuring focused and effective communication among agents.</p>
|
|
||||||
|
|
||||||
<h3 class="title is-4">Types of Agent Interactions</h3>
|
|
||||||
<p>Unlike previous frameworks that rely heavily on unstructured dialogue, our agents communicate through structured reports and diagrams, preserving essential information and enabling direct queries from the global state.</p>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li><strong>Analyst Team:</strong> Compiles research into concise analysis reports.</li>
|
|
||||||
<li><strong>Traders:</strong> Review analyst reports and produce decision signals with detailed rationales.</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<p>Natural language dialogue is reserved for specific interactions, such as debates within the Researcher and Risk Management teams, fostering deeper reasoning and balanced decision-making.</p>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li><strong>Researcher Team:</strong> Engages in debates to form balanced perspectives.</li>
|
|
||||||
<li><strong>Risk Management Team:</strong> Deliberates on trading plans from multiple risk perspectives.</li>
|
|
||||||
<li><strong>Fund Manager:</strong> Reviews and approves risk-adjusted trading decisions.</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h3 class="title is-4">Backbone LLMs</h3>
|
|
||||||
<p>We select LLMs based on task requirements, using quick-thinking models for data retrieval and deep-thinking models for in-depth analysis and decision-making. This strategic alignment ensures efficiency and robust reasoning, allowing <strong>TradingAgents</strong> to operate without the need for GPUs and enabling easy integration of alternative models in the future.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="section">
|
|
||||||
<div class="container is-max-desktop">
|
|
||||||
<div class="columns is-centered">
|
|
||||||
<div class="column is-full-width">
|
|
||||||
<h2 class="title is-3">Experiments</h2>
|
|
||||||
<div class="content has-text-justified">
|
|
||||||
<p>We evaluated <strong>TradingAgents</strong> using a comprehensive experimental setup to assess its performance against various baselines.</p>
|
|
||||||
|
|
||||||
<h3 class="title is-4">Back Trading</h3>
|
|
||||||
<p>Our simulation utilized a multi-asset, multi-modal financial dataset including historical stock prices, news articles, social media sentiments, insider transactions, financial reports, and technical indicators from January to March 2024.</p>
|
|
||||||
|
|
||||||
<h3 class="title is-4">Simulation Setup</h3>
|
|
||||||
<p>The trading environment spanned from June to November 2024. Agents operated on a daily basis, making decisions based on available data without future information, ensuring unbiased results.</p>
|
|
||||||
|
|
||||||
<h3 class="title is-4">Baseline Models</h3>
|
|
||||||
<p>We compared <strong>TradingAgents</strong> against the following strategies:</p>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li><strong>Buy and Hold:</strong> Investing equally across selected stocks throughout the period.</li>
|
|
||||||
<li><strong>MACD:</strong> Momentum strategy based on MACD crossovers.</li>
|
|
||||||
<li><strong>KDJ & RSI:</strong> Combined momentum indicators for trading signals.</li>
|
|
||||||
<li><strong>ZMR:</strong> Mean reversion strategy based on price deviations.</li>
|
|
||||||
<li><strong>SMA:</strong> Trend-following strategy using moving average crossovers.</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h3 class="title is-4">Evaluation Metrics</h3>
|
|
||||||
|
|
||||||
<div class="columns">
|
|
||||||
<div class="column">
|
|
||||||
<figure class="image">
|
|
||||||
<img src="./static/images/CumulativeReturns_AAPL.png" alt="Cumulative Returns on AAPL">
|
|
||||||
<figcaption class="has-text-centered"><strong>(a)</strong> Cumulative Returns on AAPL</figcaption>
|
|
||||||
</figure>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="column">
|
|
||||||
<figure class="image">
|
|
||||||
<img src="./static/images/TradingAgents_Transactions_AAPL.png" alt="TradingAgents Transactions for AAPL">
|
|
||||||
<figcaption class="has-text-centered">
|
|
||||||
<strong>(b)</strong> TradingAgents Transactions for AAPL.<br>
|
|
||||||
Green / Red Arrows for Long / Short Positions.
|
|
||||||
</figcaption>
|
|
||||||
</figure>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<table class="table is-striped is-fullwidth is-centered">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Categories</th>
|
|
||||||
<th>Models</th>
|
|
||||||
<th colspan="4">AAPL</th>
|
|
||||||
<th></th>
|
|
||||||
<th colspan="4">GOOGL</th>
|
|
||||||
<th></th>
|
|
||||||
<th colspan="4">AMZN</th>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th></th>
|
|
||||||
<th></th>
|
|
||||||
<th>CR%↑</th>
|
|
||||||
<th>ARR%↑</th>
|
|
||||||
<th>SR↑</th>
|
|
||||||
<th>MDD%↓</th>
|
|
||||||
<th></th>
|
|
||||||
<th>CR%↑</th>
|
|
||||||
<th>ARR%↑</th>
|
|
||||||
<th>SR↑</th>
|
|
||||||
<th>MDD%↓</th>
|
|
||||||
<th></th>
|
|
||||||
<th>CR%↑</th>
|
|
||||||
<th>ARR%↑</th>
|
|
||||||
<th>SR↑</th>
|
|
||||||
<th>MDD%↓</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td>Market</td>
|
|
||||||
<td>B&H</td>
|
|
||||||
<td>-5.23</td><td>-5.09</td><td>-1.29</td><td>11.90</td>
|
|
||||||
<td></td>
|
|
||||||
<td>7.78</td><td>8.09</td><td>1.35</td><td>13.04</td>
|
|
||||||
<td></td>
|
|
||||||
<td>17.1</td><td>17.6</td><td>3.53</td><td>3.80</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td rowspan="4">Rule-based</td>
|
|
||||||
<td>MACD</td>
|
|
||||||
<td>-1.49</td><td>-1.48</td><td>-0.81</td><td>4.53</td>
|
|
||||||
<td></td>
|
|
||||||
<td>6.20</td><td>6.26</td><td>2.31</td><td>1.22</td>
|
|
||||||
<td></td>
|
|
||||||
<td>-</td><td>-</td><td>-</td><td>-</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>KDJ&RSI</td>
|
|
||||||
<td>2.05</td><td>2.07</td><td>1.64</td><td>1.09</td>
|
|
||||||
<td></td>
|
|
||||||
<td>0.4</td><td>0.4</td><td>0.02</td><td>1.58</td>
|
|
||||||
<td></td>
|
|
||||||
<td>-0.77</td><td>-0.76</td><td>-2.25</td><td>1.08</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>ZMR</td>
|
|
||||||
<td>0.57</td><td>0.57</td><td>0.17</td><td>0.86</td>
|
|
||||||
<td></td>
|
|
||||||
<td>-0.58</td><td>0.58</td><td>2.12</td><td>2.34</td>
|
|
||||||
<td></td>
|
|
||||||
<td>-0.77</td><td>-0.77</td><td>-2.45</td><td>0.82</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>SMA</td>
|
|
||||||
<td>-3.2</td><td>-2.97</td><td>-1.72</td><td>3.67</td>
|
|
||||||
<td></td>
|
|
||||||
<td>6.23</td><td>6.43</td><td>2.12</td><td>2.34</td>
|
|
||||||
<td></td>
|
|
||||||
<td>11.01</td><td>11.6</td><td>2.22</td><td>3.97</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td rowspan="1">Ours</td>
|
|
||||||
<td><strong>TradingAgents</strong></td>
|
|
||||||
<td><strong style="color:green;">26.62</strong></td><td><strong style="color:green;">30.5</strong></td><td><strong style="color:green;">8.21</strong></td><td>0.91</td>
|
|
||||||
<td></td>
|
|
||||||
<td><strong style="color:green;">24.36</strong></td><td><strong style="color:green;">27.58</strong></td><td><strong style="color:green;">6.39</strong></td><td>1.69</td>
|
|
||||||
<td></td>
|
|
||||||
<td><strong style="color:green;">23.21</strong></td><td><strong style="color:green;">24.90</strong></td><td><strong style="color:green;">5.60</strong></td><td>2.11</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td colspan="2">Improvement(%)</td>
|
|
||||||
<td>24.57</td><td>28.43</td><td>6.57</td><td>-</td>
|
|
||||||
<td></td>
|
|
||||||
<td>16.58</td><td>19.49</td><td>4.26</td><td>-</td>
|
|
||||||
<td></td>
|
|
||||||
<td>6.10</td><td>7.30</td><td>2.07</td><td>-</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<p class="has-text-centered"><strong>Table 1:</strong> TradingAgents: Performance Metrics Comparison across AAPL, GOOGL, and AMZN.</p>
|
|
||||||
|
|
||||||
<h3 class="title is-4">Sharpe Ratio</h3>
|
|
||||||
<p><strong>TradingAgents</strong> achieves superior risk-adjusted returns, consistently outperforming all baselines across AAPL, GOOGL, and AMZN. The enhanced Sharpe Ratios demonstrate the framework's effectiveness in balancing returns with risk, highlighting its robustness in diverse market conditions.</p>
|
|
||||||
|
|
||||||
<h3 class="title is-4">Maximum Drawdown</h3>
|
|
||||||
<p>While rule-based strategies excel in controlling risk, <strong>TradingAgents</strong> maintains a low maximum drawdown without sacrificing high returns. This balance underscores the framework's ability to maximize profits while effectively managing risk.</p>
|
|
||||||
|
|
||||||
<h3 class="title is-4">Explainability</h3>
|
|
||||||
<p>Unlike traditional deep learning models, <strong>TradingAgents</strong> offers transparent decision-making through natural language explanations. Each agent's actions are accompanied by detailed reasoning and tool usage, making the system's operations easily interpretable and debuggable, which is crucial for real-world financial applications.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="section">
|
|
||||||
<div class="container is-max-desktop">
|
|
||||||
<div class="columns is-centered">
|
|
||||||
<div class="column is-full-width">
|
|
||||||
<h2 class="title is-3">Conclusion</h2>
|
|
||||||
<div class="content has-text-justified">
|
|
||||||
<p>We presented <strong>TradingAgents</strong>, a multi-agent LLM-driven stock trading framework that emulates a realistic trading firm with specialized agents collaborating through debates and structured communication. Our framework leverages diverse data sources and multi-agent interactions to enhance trading decisions, achieving superior performance in cumulative returns, Sharpe ratio, and risk management compared to traditional strategies. Future work includes live deployment, expanding agent roles, and integrating real-time data processing to further improve performance.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="citation-ref" class="section">
|
|
||||||
<div class="container content">
|
|
||||||
<h2 class="title">BibTeX</h2>
|
|
||||||
<pre><code>@inproceedings{xiao2025tradingagentsmultiagentsllmfinancial,
|
|
||||||
title = {TradingAgents: Multi-Agents LLM Financial Trading Framework},
|
|
||||||
author = {Yijia Xiao and Edward Sun and Di Luo and Wei Wang},
|
|
||||||
booktitle = {Multi-Agent AI in the Real World @ AAAI 2025},
|
|
||||||
year = {2025},
|
|
||||||
eprint = {2412.20138},
|
|
||||||
archivePrefix= {arXiv},
|
|
||||||
primaryClass = {q-fin.TR},
|
|
||||||
url = {https://arxiv.org/abs/2412.20138},
|
|
||||||
note = {Workshop paper},
|
|
||||||
}</code></pre>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<footer class="footer">
|
|
||||||
<div class="container">
|
|
||||||
<div class="content has-text-centered">
|
|
||||||
<a class="icon-link" href="https://arxiv.org/abs/2412.20138"><i class="fas fa-file-pdf"></i></a>
|
|
||||||
<a class="icon-link" href="https://github.com/TradingAgents-AI"><i class="fab fa-github"></i></a>
|
|
||||||
</div>
|
|
||||||
<div class="columns is-centered">
|
|
||||||
<div class="column is-8">
|
|
||||||
<div class="content">
|
|
||||||
<p>This website is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">Creative Commons Attribution-ShareAlike 4.0 International License</a>.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</footer>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
6
main.py
6
main.py
@@ -3,8 +3,10 @@ from tradingagents.default_config import DEFAULT_CONFIG
|
|||||||
|
|
||||||
# Create a custom config
|
# Create a custom config
|
||||||
config = DEFAULT_CONFIG.copy()
|
config = DEFAULT_CONFIG.copy()
|
||||||
config["deep_think_llm"] = "gpt-4.1-nano" # Use a different model
|
config["llm_provider"] = "google" # Use a different model
|
||||||
config["quick_think_llm"] = "gpt-4.1-nano" # Use a different model
|
config["backend_url"] = "https://generativelanguage.googleapis.com/v1" # Use a different backend
|
||||||
|
config["deep_think_llm"] = "gemini-2.0-flash" # Use a different model
|
||||||
|
config["quick_think_llm"] = "gemini-2.0-flash" # Use a different model
|
||||||
config["max_debate_rounds"] = 1 # Increase debate rounds
|
config["max_debate_rounds"] = 1 # Increase debate rounds
|
||||||
config["online_tools"] = True # Increase debate rounds
|
config["online_tools"] = True # Increase debate rounds
|
||||||
|
|
||||||
|
|||||||
34
pyproject.toml
Normal file
34
pyproject.toml
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
[project]
|
||||||
|
name = "tradingagents"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "Add your description here"
|
||||||
|
readme = "README.md"
|
||||||
|
requires-python = ">=3.10"
|
||||||
|
dependencies = [
|
||||||
|
"akshare>=1.16.98",
|
||||||
|
"backtrader>=1.9.78.123",
|
||||||
|
"chainlit>=2.5.5",
|
||||||
|
"chromadb>=1.0.12",
|
||||||
|
"eodhd>=1.0.32",
|
||||||
|
"feedparser>=6.0.11",
|
||||||
|
"finnhub-python>=2.4.23",
|
||||||
|
"langchain-anthropic>=0.3.15",
|
||||||
|
"langchain-experimental>=0.3.4",
|
||||||
|
"langchain-google-genai>=2.1.5",
|
||||||
|
"langchain-openai>=0.3.23",
|
||||||
|
"langgraph>=0.4.8",
|
||||||
|
"pandas>=2.3.0",
|
||||||
|
"parsel>=1.10.0",
|
||||||
|
"praw>=7.8.1",
|
||||||
|
"pytz>=2025.2",
|
||||||
|
"questionary>=2.1.0",
|
||||||
|
"redis>=6.2.0",
|
||||||
|
"requests>=2.32.4",
|
||||||
|
"rich>=14.0.0",
|
||||||
|
"setuptools>=80.9.0",
|
||||||
|
"stockstats>=0.6.5",
|
||||||
|
"tqdm>=4.67.1",
|
||||||
|
"tushare>=1.4.21",
|
||||||
|
"typing-extensions>=4.14.0",
|
||||||
|
"yfinance>=0.2.63",
|
||||||
|
]
|
||||||
@@ -22,3 +22,5 @@ redis
|
|||||||
chainlit
|
chainlit
|
||||||
rich
|
rich
|
||||||
questionary
|
questionary
|
||||||
|
langchain_anthropic
|
||||||
|
langchain-google-genai
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ def create_fundamentals_analyst(llm, toolkit):
|
|||||||
|
|
||||||
system_message = (
|
system_message = (
|
||||||
"You are a researcher tasked with analyzing fundamental information over the past week about a company. Please write a comprehensive report of the company's fundamental information such as financial documents, company profile, basic company financials, company financial history, insider sentiment and insider transactions to gain a full view of the company's fundamental information to inform traders. Make sure to include as much detail as possible. Do not simply state the trends are mixed, provide detailed and finegrained analysis and insights that may help traders make decisions."
|
"You are a researcher tasked with analyzing fundamental information over the past week about a company. Please write a comprehensive report of the company's fundamental information such as financial documents, company profile, basic company financials, company financial history, insider sentiment and insider transactions to gain a full view of the company's fundamental information to inform traders. Make sure to include as much detail as possible. Do not simply state the trends are mixed, provide detailed and finegrained analysis and insights that may help traders make decisions."
|
||||||
+ " Make sure to append a Makrdown table at the end of the report to organize key points in the report, organized and easy to read.",
|
+ " Make sure to append a Markdown table at the end of the report to organize key points in the report, organized and easy to read.",
|
||||||
)
|
)
|
||||||
|
|
||||||
prompt = ChatPromptTemplate.from_messages(
|
prompt = ChatPromptTemplate.from_messages(
|
||||||
@@ -51,9 +51,14 @@ def create_fundamentals_analyst(llm, toolkit):
|
|||||||
|
|
||||||
result = chain.invoke(state["messages"])
|
result = chain.invoke(state["messages"])
|
||||||
|
|
||||||
|
report = ""
|
||||||
|
|
||||||
|
if len(result.tool_calls) == 0:
|
||||||
|
report = result.content
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"messages": [result],
|
"messages": [result],
|
||||||
"fundamentals_report": result.content,
|
"fundamentals_report": report,
|
||||||
}
|
}
|
||||||
|
|
||||||
return fundamentals_analyst_node
|
return fundamentals_analyst_node
|
||||||
|
|||||||
@@ -76,9 +76,14 @@ Volume-Based Indicators:
|
|||||||
|
|
||||||
result = chain.invoke(state["messages"])
|
result = chain.invoke(state["messages"])
|
||||||
|
|
||||||
|
report = ""
|
||||||
|
|
||||||
|
if len(result.tool_calls) == 0:
|
||||||
|
report = result.content
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"messages": [result],
|
"messages": [result],
|
||||||
"market_report": result.content,
|
"market_report": report,
|
||||||
}
|
}
|
||||||
|
|
||||||
return market_analyst_node
|
return market_analyst_node
|
||||||
|
|||||||
@@ -47,9 +47,14 @@ def create_news_analyst(llm, toolkit):
|
|||||||
chain = prompt | llm.bind_tools(tools)
|
chain = prompt | llm.bind_tools(tools)
|
||||||
result = chain.invoke(state["messages"])
|
result = chain.invoke(state["messages"])
|
||||||
|
|
||||||
|
report = ""
|
||||||
|
|
||||||
|
if len(result.tool_calls) == 0:
|
||||||
|
report = result.content
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"messages": [result],
|
"messages": [result],
|
||||||
"news_report": result.content,
|
"news_report": report,
|
||||||
}
|
}
|
||||||
|
|
||||||
return news_analyst_node
|
return news_analyst_node
|
||||||
|
|||||||
@@ -47,9 +47,14 @@ def create_social_media_analyst(llm, toolkit):
|
|||||||
|
|
||||||
result = chain.invoke(state["messages"])
|
result = chain.invoke(state["messages"])
|
||||||
|
|
||||||
|
report = ""
|
||||||
|
|
||||||
|
if len(result.tool_calls) == 0:
|
||||||
|
report = result.content
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"messages": [result],
|
"messages": [result],
|
||||||
"sentiment_report": result.content,
|
"sentiment_report": report,
|
||||||
}
|
}
|
||||||
|
|
||||||
return social_media_analyst_node
|
return social_media_analyst_node
|
||||||
|
|||||||
@@ -12,13 +12,21 @@ from dateutil.relativedelta import relativedelta
|
|||||||
from langchain_openai import ChatOpenAI
|
from langchain_openai import ChatOpenAI
|
||||||
import tradingagents.dataflows.interface as interface
|
import tradingagents.dataflows.interface as interface
|
||||||
from tradingagents.default_config import DEFAULT_CONFIG
|
from tradingagents.default_config import DEFAULT_CONFIG
|
||||||
|
from langchain_core.messages import HumanMessage
|
||||||
|
|
||||||
|
|
||||||
def create_msg_delete():
|
def create_msg_delete():
|
||||||
def delete_messages(state):
|
def delete_messages(state):
|
||||||
"""To prevent message history from overflowing, regularly clear message history after a stage of the pipeline is done"""
|
"""Clear messages and add placeholder for Anthropic compatibility"""
|
||||||
messages = state["messages"]
|
messages = state["messages"]
|
||||||
return {"messages": [RemoveMessage(id=m.id) for m in messages]}
|
|
||||||
|
# Remove all messages
|
||||||
|
removal_operations = [RemoveMessage(id=m.id) for m in messages]
|
||||||
|
|
||||||
|
# Add a minimal placeholder message
|
||||||
|
placeholder = HumanMessage(content="Continue")
|
||||||
|
|
||||||
|
return {"messages": removal_operations + [placeholder]}
|
||||||
|
|
||||||
return delete_messages
|
return delete_messages
|
||||||
|
|
||||||
@@ -116,7 +124,7 @@ class Toolkit:
|
|||||||
def get_YFin_data(
|
def get_YFin_data(
|
||||||
symbol: Annotated[str, "ticker symbol of the company"],
|
symbol: Annotated[str, "ticker symbol of the company"],
|
||||||
start_date: Annotated[str, "Start date in yyyy-mm-dd format"],
|
start_date: Annotated[str, "Start date in yyyy-mm-dd format"],
|
||||||
end_date: Annotated[str, "Start date in yyyy-mm-dd format"],
|
end_date: Annotated[str, "End date in yyyy-mm-dd format"],
|
||||||
) -> str:
|
) -> str:
|
||||||
"""
|
"""
|
||||||
Retrieve the stock price data for a given ticker symbol from Yahoo Finance.
|
Retrieve the stock price data for a given ticker symbol from Yahoo Finance.
|
||||||
@@ -137,7 +145,7 @@ class Toolkit:
|
|||||||
def get_YFin_data_online(
|
def get_YFin_data_online(
|
||||||
symbol: Annotated[str, "ticker symbol of the company"],
|
symbol: Annotated[str, "ticker symbol of the company"],
|
||||||
start_date: Annotated[str, "Start date in yyyy-mm-dd format"],
|
start_date: Annotated[str, "Start date in yyyy-mm-dd format"],
|
||||||
end_date: Annotated[str, "Start date in yyyy-mm-dd format"],
|
end_date: Annotated[str, "End date in yyyy-mm-dd format"],
|
||||||
) -> str:
|
) -> str:
|
||||||
"""
|
"""
|
||||||
Retrieve the stock price data for a given ticker symbol from Yahoo Finance.
|
Retrieve the stock price data for a given ticker symbol from Yahoo Finance.
|
||||||
|
|||||||
@@ -1,19 +1,23 @@
|
|||||||
import chromadb
|
import chromadb
|
||||||
from chromadb.config import Settings
|
from chromadb.config import Settings
|
||||||
from openai import OpenAI
|
from openai import OpenAI
|
||||||
import numpy as np
|
|
||||||
|
|
||||||
|
|
||||||
class FinancialSituationMemory:
|
class FinancialSituationMemory:
|
||||||
def __init__(self, name):
|
def __init__(self, name, config):
|
||||||
self.client = OpenAI()
|
if config["backend_url"] == "http://localhost:11434/v1":
|
||||||
|
self.embedding = "nomic-embed-text"
|
||||||
|
else:
|
||||||
|
self.embedding = "text-embedding-3-small"
|
||||||
|
self.client = OpenAI(base_url=config["backend_url"])
|
||||||
self.chroma_client = chromadb.Client(Settings(allow_reset=True))
|
self.chroma_client = chromadb.Client(Settings(allow_reset=True))
|
||||||
self.situation_collection = self.chroma_client.create_collection(name=name)
|
self.situation_collection = self.chroma_client.create_collection(name=name)
|
||||||
|
|
||||||
def get_embedding(self, text):
|
def get_embedding(self, text):
|
||||||
"""Get OpenAI embedding for a text"""
|
"""Get OpenAI embedding for a text"""
|
||||||
|
|
||||||
response = self.client.embeddings.create(
|
response = self.client.embeddings.create(
|
||||||
model="text-embedding-ada-002", input=text
|
model=self.embedding, input=text
|
||||||
)
|
)
|
||||||
return response.data[0].embedding
|
return response.data[0].embedding
|
||||||
|
|
||||||
|
|||||||
@@ -628,7 +628,7 @@ def get_YFin_data_window(
|
|||||||
def get_YFin_data_online(
|
def get_YFin_data_online(
|
||||||
symbol: Annotated[str, "ticker symbol of the company"],
|
symbol: Annotated[str, "ticker symbol of the company"],
|
||||||
start_date: Annotated[str, "Start date in yyyy-mm-dd format"],
|
start_date: Annotated[str, "Start date in yyyy-mm-dd format"],
|
||||||
end_date: Annotated[str, "Start date in yyyy-mm-dd format"],
|
end_date: Annotated[str, "End date in yyyy-mm-dd format"],
|
||||||
):
|
):
|
||||||
|
|
||||||
datetime.strptime(start_date, "%Y-%m-%d")
|
datetime.strptime(start_date, "%Y-%m-%d")
|
||||||
@@ -670,7 +670,7 @@ def get_YFin_data_online(
|
|||||||
def get_YFin_data(
|
def get_YFin_data(
|
||||||
symbol: Annotated[str, "ticker symbol of the company"],
|
symbol: Annotated[str, "ticker symbol of the company"],
|
||||||
start_date: Annotated[str, "Start date in yyyy-mm-dd format"],
|
start_date: Annotated[str, "Start date in yyyy-mm-dd format"],
|
||||||
end_date: Annotated[str, "Start date in yyyy-mm-dd format"],
|
end_date: Annotated[str, "End date in yyyy-mm-dd format"],
|
||||||
) -> str:
|
) -> str:
|
||||||
# read in data
|
# read in data
|
||||||
data = pd.read_csv(
|
data = pd.read_csv(
|
||||||
@@ -703,17 +703,18 @@ def get_YFin_data(
|
|||||||
|
|
||||||
|
|
||||||
def get_stock_news_openai(ticker, curr_date):
|
def get_stock_news_openai(ticker, curr_date):
|
||||||
client = OpenAI()
|
config = get_config()
|
||||||
|
client = OpenAI(base_url=config["backend_url"])
|
||||||
|
|
||||||
response = client.responses.create(
|
response = client.responses.create(
|
||||||
model="gpt-4.1-mini",
|
model=config["quick_think_llm"],
|
||||||
input=[
|
input=[
|
||||||
{
|
{
|
||||||
"role": "system",
|
"role": "system",
|
||||||
"content": [
|
"content": [
|
||||||
{
|
{
|
||||||
"type": "input_text",
|
"type": "input_text",
|
||||||
"text": f"Can you search Social Media for {ticker} on TSLA from 7 days before {curr_date} to {curr_date}? Make sure you only get the data posted during that period.",
|
"text": f"Can you search Social Media for {ticker} from 7 days before {curr_date} to {curr_date}? Make sure you only get the data posted during that period.",
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
@@ -737,10 +738,11 @@ def get_stock_news_openai(ticker, curr_date):
|
|||||||
|
|
||||||
|
|
||||||
def get_global_news_openai(curr_date):
|
def get_global_news_openai(curr_date):
|
||||||
client = OpenAI()
|
config = get_config()
|
||||||
|
client = OpenAI(base_url=config["backend_url"])
|
||||||
|
|
||||||
response = client.responses.create(
|
response = client.responses.create(
|
||||||
model="gpt-4.1-mini",
|
model=config["quick_think_llm"],
|
||||||
input=[
|
input=[
|
||||||
{
|
{
|
||||||
"role": "system",
|
"role": "system",
|
||||||
@@ -771,10 +773,11 @@ def get_global_news_openai(curr_date):
|
|||||||
|
|
||||||
|
|
||||||
def get_fundamentals_openai(ticker, curr_date):
|
def get_fundamentals_openai(ticker, curr_date):
|
||||||
client = OpenAI()
|
config = get_config()
|
||||||
|
client = OpenAI(base_url=config["backend_url"])
|
||||||
|
|
||||||
response = client.responses.create(
|
response = client.responses.create(
|
||||||
model="gpt-4.1-mini",
|
model=config["quick_think_llm"],
|
||||||
input=[
|
input=[
|
||||||
{
|
{
|
||||||
"role": "system",
|
"role": "system",
|
||||||
|
|||||||
@@ -2,14 +2,17 @@ import os
|
|||||||
|
|
||||||
DEFAULT_CONFIG = {
|
DEFAULT_CONFIG = {
|
||||||
"project_dir": os.path.abspath(os.path.join(os.path.dirname(__file__), ".")),
|
"project_dir": os.path.abspath(os.path.join(os.path.dirname(__file__), ".")),
|
||||||
|
"results_dir": os.getenv("TRADINGAGENTS_RESULTS_DIR", "./results"),
|
||||||
"data_dir": "/Users/yluo/Documents/Code/ScAI/FR1-data",
|
"data_dir": "/Users/yluo/Documents/Code/ScAI/FR1-data",
|
||||||
"data_cache_dir": os.path.join(
|
"data_cache_dir": os.path.join(
|
||||||
os.path.abspath(os.path.join(os.path.dirname(__file__), ".")),
|
os.path.abspath(os.path.join(os.path.dirname(__file__), ".")),
|
||||||
"dataflows/data_cache",
|
"dataflows/data_cache",
|
||||||
),
|
),
|
||||||
# LLM settings
|
# LLM settings
|
||||||
|
"llm_provider": "openai",
|
||||||
"deep_think_llm": "o4-mini",
|
"deep_think_llm": "o4-mini",
|
||||||
"quick_think_llm": "gpt-4o-mini",
|
"quick_think_llm": "gpt-4o-mini",
|
||||||
|
"backend_url": "https://api.openai.com/v1",
|
||||||
# Debate and discussion settings
|
# Debate and discussion settings
|
||||||
"max_debate_rounds": 1,
|
"max_debate_rounds": 1,
|
||||||
"max_risk_discuss_rounds": 1,
|
"max_risk_discuss_rounds": 1,
|
||||||
|
|||||||
@@ -7,6 +7,9 @@ from datetime import date
|
|||||||
from typing import Dict, Any, Tuple, List, Optional
|
from typing import Dict, Any, Tuple, List, Optional
|
||||||
|
|
||||||
from langchain_openai import ChatOpenAI
|
from langchain_openai import ChatOpenAI
|
||||||
|
from langchain_anthropic import ChatAnthropic
|
||||||
|
from langchain_google_genai import ChatGoogleGenerativeAI
|
||||||
|
|
||||||
from langgraph.prebuilt import ToolNode
|
from langgraph.prebuilt import ToolNode
|
||||||
|
|
||||||
from tradingagents.agents import *
|
from tradingagents.agents import *
|
||||||
@@ -55,18 +58,26 @@ class TradingAgentsGraph:
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Initialize LLMs
|
# Initialize LLMs
|
||||||
self.deep_thinking_llm = ChatOpenAI(model=self.config["deep_think_llm"])
|
if self.config["llm_provider"].lower() == "openai" or self.config["llm_provider"] == "ollama" or self.config["llm_provider"] == "openrouter":
|
||||||
self.quick_thinking_llm = ChatOpenAI(
|
self.deep_thinking_llm = ChatOpenAI(model=self.config["deep_think_llm"], base_url=self.config["backend_url"])
|
||||||
model=self.config["quick_think_llm"], temperature=0.1
|
self.quick_thinking_llm = ChatOpenAI(model=self.config["quick_think_llm"], base_url=self.config["backend_url"])
|
||||||
)
|
elif self.config["llm_provider"].lower() == "anthropic":
|
||||||
|
self.deep_thinking_llm = ChatAnthropic(model=self.config["deep_think_llm"], base_url=self.config["backend_url"])
|
||||||
|
self.quick_thinking_llm = ChatAnthropic(model=self.config["quick_think_llm"], base_url=self.config["backend_url"])
|
||||||
|
elif self.config["llm_provider"].lower() == "google":
|
||||||
|
self.deep_thinking_llm = ChatGoogleGenerativeAI(model=self.config["deep_think_llm"])
|
||||||
|
self.quick_thinking_llm = ChatGoogleGenerativeAI(model=self.config["quick_think_llm"])
|
||||||
|
else:
|
||||||
|
raise ValueError(f"Unsupported LLM provider: {self.config['llm_provider']}")
|
||||||
|
|
||||||
self.toolkit = Toolkit(config=self.config)
|
self.toolkit = Toolkit(config=self.config)
|
||||||
|
|
||||||
# Initialize memories
|
# Initialize memories
|
||||||
self.bull_memory = FinancialSituationMemory("bull_memory")
|
self.bull_memory = FinancialSituationMemory("bull_memory", self.config)
|
||||||
self.bear_memory = FinancialSituationMemory("bear_memory")
|
self.bear_memory = FinancialSituationMemory("bear_memory", self.config)
|
||||||
self.trader_memory = FinancialSituationMemory("trader_memory")
|
self.trader_memory = FinancialSituationMemory("trader_memory", self.config)
|
||||||
self.invest_judge_memory = FinancialSituationMemory("invest_judge_memory")
|
self.invest_judge_memory = FinancialSituationMemory("invest_judge_memory", self.config)
|
||||||
self.risk_manager_memory = FinancialSituationMemory("risk_manager_memory")
|
self.risk_manager_memory = FinancialSituationMemory("risk_manager_memory", self.config)
|
||||||
|
|
||||||
# Create tool nodes
|
# Create tool nodes
|
||||||
self.tool_nodes = self._create_tool_nodes()
|
self.tool_nodes = self._create_tool_nodes()
|
||||||
|
|||||||
Reference in New Issue
Block a user