Merge commit '3165da542a92b9f624e8ce4ca7417069d264cf29' into dev-leo
This commit is contained in:
commit
941abbe69f
143
cli/main.py
143
cli/main.py
|
|
@ -25,12 +25,14 @@ from tradingagents.graph.trading_graph import TradingAgentsGraph
|
||||||
from tradingagents.default_config import DEFAULT_CONFIG
|
from tradingagents.default_config import DEFAULT_CONFIG
|
||||||
from cli.models import AnalystType
|
from cli.models import AnalystType
|
||||||
from cli.utils import *
|
from cli.utils import *
|
||||||
|
from tradingagents.i18n import get_lang
|
||||||
|
|
||||||
console = Console()
|
console = Console()
|
||||||
|
lang = get_lang()
|
||||||
|
|
||||||
app = typer.Typer(
|
app = typer.Typer(
|
||||||
name="TradingAgents",
|
name="TradingAgents",
|
||||||
help="TradingAgents CLI: Multi-Agents LLM Financial Trading Framework",
|
help=lang["welcome"] + ": " + lang["framework_subtitle"],
|
||||||
add_completion=True, # Enable shell completion
|
add_completion=True, # Enable shell completion
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -44,22 +46,22 @@ class MessageBuffer:
|
||||||
self.final_report = None # Store the complete final report
|
self.final_report = None # Store the complete final report
|
||||||
self.agent_status = {
|
self.agent_status = {
|
||||||
# Analyst Team
|
# Analyst Team
|
||||||
"Market Analyst": "pending",
|
lang["market_analyst"]: lang["pending"],
|
||||||
"Social Analyst": "pending",
|
lang["social_analyst"]: lang["pending"],
|
||||||
"News Analyst": "pending",
|
lang["news_analyst"]: lang["pending"],
|
||||||
"Fundamentals Analyst": "pending",
|
lang["fundamentals_analyst"]: lang["pending"],
|
||||||
# Research Team
|
# Research Team
|
||||||
"Bull Researcher": "pending",
|
lang["bull_researcher"]: lang["pending"],
|
||||||
"Bear Researcher": "pending",
|
lang["bear_researcher"]: lang["pending"],
|
||||||
"Research Manager": "pending",
|
lang["research_manager"]: lang["pending"],
|
||||||
# Trading Team
|
# Trading Team
|
||||||
"Trader": "pending",
|
lang["trader"]: lang["pending"],
|
||||||
# Risk Management Team
|
# Risk Management Team
|
||||||
"Risky Analyst": "pending",
|
lang["risky_analyst"]: lang["pending"],
|
||||||
"Neutral Analyst": "pending",
|
lang["neutral_analyst"]: lang["pending"],
|
||||||
"Safe Analyst": "pending",
|
lang["safe_analyst"]: lang["pending"],
|
||||||
# Portfolio Management Team
|
# Portfolio Management Team
|
||||||
"Portfolio Manager": "pending",
|
lang["portfolio_manager"]: lang["pending"],
|
||||||
}
|
}
|
||||||
self.current_agent = None
|
self.current_agent = None
|
||||||
self.report_sections = {
|
self.report_sections = {
|
||||||
|
|
@ -104,13 +106,13 @@ class MessageBuffer:
|
||||||
if latest_section and latest_content:
|
if latest_section and latest_content:
|
||||||
# Format the current section for display
|
# Format the current section for display
|
||||||
section_titles = {
|
section_titles = {
|
||||||
"market_report": "Market Analysis",
|
"market_report": lang["market_report"],
|
||||||
"sentiment_report": "Social Sentiment",
|
"sentiment_report": lang["sentiment_report"],
|
||||||
"news_report": "News Analysis",
|
"news_report": lang["news_report"],
|
||||||
"fundamentals_report": "Fundamentals Analysis",
|
"fundamentals_report": lang["fundamentals_report"],
|
||||||
"investment_plan": "Research Team Decision",
|
"investment_plan": lang["investment_plan"],
|
||||||
"trader_investment_plan": "Trading Team Plan",
|
"trader_investment_plan": lang["trader_investment_plan"],
|
||||||
"final_trade_decision": "Portfolio Management Decision",
|
"final_trade_decision": lang["final_trade_decision"],
|
||||||
}
|
}
|
||||||
self.current_report = (
|
self.current_report = (
|
||||||
f"### {section_titles[latest_section]}\n{latest_content}"
|
f"### {section_titles[latest_section]}\n{latest_content}"
|
||||||
|
|
@ -132,37 +134,37 @@ class MessageBuffer:
|
||||||
"fundamentals_report",
|
"fundamentals_report",
|
||||||
]
|
]
|
||||||
):
|
):
|
||||||
report_parts.append("## Analyst Team Reports")
|
report_parts.append(f"## {lang['analyst_team']}")
|
||||||
if self.report_sections["market_report"]:
|
if self.report_sections["market_report"]:
|
||||||
report_parts.append(
|
report_parts.append(
|
||||||
f"### Market Analysis\n{self.report_sections['market_report']}"
|
f"### {lang['market_report']}\n{self.report_sections['market_report']}"
|
||||||
)
|
)
|
||||||
if self.report_sections["sentiment_report"]:
|
if self.report_sections["sentiment_report"]:
|
||||||
report_parts.append(
|
report_parts.append(
|
||||||
f"### Social Sentiment\n{self.report_sections['sentiment_report']}"
|
f"### {lang['sentiment_report']}\n{self.report_sections['sentiment_report']}"
|
||||||
)
|
)
|
||||||
if self.report_sections["news_report"]:
|
if self.report_sections["news_report"]:
|
||||||
report_parts.append(
|
report_parts.append(
|
||||||
f"### News Analysis\n{self.report_sections['news_report']}"
|
f"### {lang['news_report']}\n{self.report_sections['news_report']}"
|
||||||
)
|
)
|
||||||
if self.report_sections["fundamentals_report"]:
|
if self.report_sections["fundamentals_report"]:
|
||||||
report_parts.append(
|
report_parts.append(
|
||||||
f"### Fundamentals Analysis\n{self.report_sections['fundamentals_report']}"
|
f"### {lang['fundamentals_report']}\n{self.report_sections['fundamentals_report']}"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Research Team Reports
|
# Research Team Reports
|
||||||
if self.report_sections["investment_plan"]:
|
if self.report_sections["investment_plan"]:
|
||||||
report_parts.append("## Research Team Decision")
|
report_parts.append(f"## {lang['research_team']}")
|
||||||
report_parts.append(f"{self.report_sections['investment_plan']}")
|
report_parts.append(f"{self.report_sections['investment_plan']}")
|
||||||
|
|
||||||
# Trading Team Reports
|
# Trading Team Reports
|
||||||
if self.report_sections["trader_investment_plan"]:
|
if self.report_sections["trader_investment_plan"]:
|
||||||
report_parts.append("## Trading Team Plan")
|
report_parts.append(f"## {lang['trading_team']}")
|
||||||
report_parts.append(f"{self.report_sections['trader_investment_plan']}")
|
report_parts.append(f"{self.report_sections['trader_investment_plan']}")
|
||||||
|
|
||||||
# Portfolio Management Decision
|
# Portfolio Management Decision
|
||||||
if self.report_sections["final_trade_decision"]:
|
if self.report_sections["final_trade_decision"]:
|
||||||
report_parts.append("## Portfolio Management Decision")
|
report_parts.append(f"## {lang['portfolio_management']}")
|
||||||
report_parts.append(f"{self.report_sections['final_trade_decision']}")
|
report_parts.append(f"{self.report_sections['final_trade_decision']}")
|
||||||
|
|
||||||
self.final_report = "\n\n".join(report_parts) if report_parts else None
|
self.final_report = "\n\n".join(report_parts) if report_parts else None
|
||||||
|
|
@ -191,9 +193,9 @@ def update_display(layout, spinner_text=None):
|
||||||
# Header with welcome message
|
# Header with welcome message
|
||||||
layout["header"].update(
|
layout["header"].update(
|
||||||
Panel(
|
Panel(
|
||||||
"[bold green]Welcome to TradingAgents CLI[/bold green]\n"
|
f"[bold green]{lang['welcome']}[/bold green]\n"
|
||||||
"[dim]© [Tauric Research](https://github.com/TauricResearch)[/dim]",
|
"[dim]© [Tauric Research](https://github.com/TauricResearch)[/dim]",
|
||||||
title="Welcome to TradingAgents",
|
title=lang["welcome"],
|
||||||
border_style="green",
|
border_style="green",
|
||||||
padding=(1, 2),
|
padding=(1, 2),
|
||||||
expand=True,
|
expand=True,
|
||||||
|
|
@ -210,22 +212,22 @@ def update_display(layout, spinner_text=None):
|
||||||
padding=(0, 2), # Add horizontal padding
|
padding=(0, 2), # Add horizontal padding
|
||||||
expand=True, # Make table expand to fill available space
|
expand=True, # Make table expand to fill available space
|
||||||
)
|
)
|
||||||
progress_table.add_column("Team", style="cyan", justify="center", width=20)
|
progress_table.add_column(lang["team"], style="cyan", justify="center", width=20)
|
||||||
progress_table.add_column("Agent", style="green", justify="center", width=20)
|
progress_table.add_column(lang["agent"], style="green", justify="center", width=20)
|
||||||
progress_table.add_column("Status", style="yellow", justify="center", width=20)
|
progress_table.add_column(lang["status"], style="yellow", justify="center", width=20)
|
||||||
|
|
||||||
# Group agents by team
|
# Group agents by team
|
||||||
teams = {
|
teams = {
|
||||||
"Analyst Team": [
|
lang["analyst_team"]: [
|
||||||
"Market Analyst",
|
lang["market_analyst"],
|
||||||
"Social Analyst",
|
lang["social_analyst"],
|
||||||
"News Analyst",
|
lang["news_analyst"],
|
||||||
"Fundamentals Analyst",
|
lang["fundamentals_analyst"],
|
||||||
],
|
],
|
||||||
"Research Team": ["Bull Researcher", "Bear Researcher", "Research Manager"],
|
lang["research_team"]: [lang["bull_researcher"], lang["bear_researcher"], lang["research_manager"]],
|
||||||
"Trading Team": ["Trader"],
|
lang["trading_team"]: [lang["trader"]],
|
||||||
"Risk Management": ["Risky Analyst", "Neutral Analyst", "Safe Analyst"],
|
lang["risk_management"]: [lang["risky_analyst"], lang["neutral_analyst"], lang["safe_analyst"]],
|
||||||
"Portfolio Management": ["Portfolio Manager"],
|
lang["portfolio_management"]: [lang["portfolio_manager"]],
|
||||||
}
|
}
|
||||||
|
|
||||||
for team, agents in teams.items():
|
for team, agents in teams.items():
|
||||||
|
|
@ -234,14 +236,14 @@ def update_display(layout, spinner_text=None):
|
||||||
status = message_buffer.agent_status[first_agent]
|
status = message_buffer.agent_status[first_agent]
|
||||||
if status == "in_progress":
|
if status == "in_progress":
|
||||||
spinner = Spinner(
|
spinner = Spinner(
|
||||||
"dots", text="[blue]in_progress[/blue]", style="bold cyan"
|
"dots", text=f"[blue]{lang['in_progress']}[/blue]", style="bold cyan"
|
||||||
)
|
)
|
||||||
status_cell = spinner
|
status_cell = spinner
|
||||||
else:
|
else:
|
||||||
status_color = {
|
status_color = {
|
||||||
"pending": "yellow",
|
lang["pending"]: "yellow",
|
||||||
"completed": "green",
|
lang["completed"]: "green",
|
||||||
"error": "red",
|
lang["error"]: "red",
|
||||||
}.get(status, "white")
|
}.get(status, "white")
|
||||||
status_cell = f"[{status_color}]{status}[/{status_color}]"
|
status_cell = f"[{status_color}]{status}[/{status_color}]"
|
||||||
progress_table.add_row(team, first_agent, status_cell)
|
progress_table.add_row(team, first_agent, status_cell)
|
||||||
|
|
@ -251,14 +253,14 @@ def update_display(layout, spinner_text=None):
|
||||||
status = message_buffer.agent_status[agent]
|
status = message_buffer.agent_status[agent]
|
||||||
if status == "in_progress":
|
if status == "in_progress":
|
||||||
spinner = Spinner(
|
spinner = Spinner(
|
||||||
"dots", text="[blue]in_progress[/blue]", style="bold cyan"
|
"dots", text=f"[blue]{lang['in_progress']}[/blue]", style="bold cyan"
|
||||||
)
|
)
|
||||||
status_cell = spinner
|
status_cell = spinner
|
||||||
else:
|
else:
|
||||||
status_color = {
|
status_color = {
|
||||||
"pending": "yellow",
|
lang["pending"]: "yellow",
|
||||||
"completed": "green",
|
lang["completed"]: "green",
|
||||||
"error": "red",
|
lang["error"]: "red",
|
||||||
}.get(status, "white")
|
}.get(status, "white")
|
||||||
status_cell = f"[{status_color}]{status}[/{status_color}]"
|
status_cell = f"[{status_color}]{status}[/{status_color}]"
|
||||||
progress_table.add_row("", agent, status_cell)
|
progress_table.add_row("", agent, status_cell)
|
||||||
|
|
@ -267,7 +269,7 @@ def update_display(layout, spinner_text=None):
|
||||||
progress_table.add_row("─" * 20, "─" * 20, "─" * 20, style="dim")
|
progress_table.add_row("─" * 20, "─" * 20, "─" * 20, style="dim")
|
||||||
|
|
||||||
layout["progress"].update(
|
layout["progress"].update(
|
||||||
Panel(progress_table, title="Progress", border_style="cyan", padding=(1, 2))
|
Panel(progress_table, title=lang["progress"], border_style="cyan", padding=(1, 2))
|
||||||
)
|
)
|
||||||
|
|
||||||
# Messages panel showing recent messages and tool calls
|
# Messages panel showing recent messages and tool calls
|
||||||
|
|
@ -282,9 +284,7 @@ def update_display(layout, spinner_text=None):
|
||||||
)
|
)
|
||||||
messages_table.add_column("Time", style="cyan", width=8, justify="center")
|
messages_table.add_column("Time", style="cyan", width=8, justify="center")
|
||||||
messages_table.add_column("Type", style="green", width=10, justify="center")
|
messages_table.add_column("Type", style="green", width=10, justify="center")
|
||||||
messages_table.add_column(
|
messages_table.add_column(lang["content"] if "content" in lang else "Content", style="white", no_wrap=False, ratio=1)
|
||||||
"Content", style="white", no_wrap=False, ratio=1
|
|
||||||
) # Make content column expand
|
|
||||||
|
|
||||||
# Combine tool calls and messages
|
# Combine tool calls and messages
|
||||||
all_messages = []
|
all_messages = []
|
||||||
|
|
@ -346,12 +346,7 @@ def update_display(layout, spinner_text=None):
|
||||||
)
|
)
|
||||||
|
|
||||||
layout["messages"].update(
|
layout["messages"].update(
|
||||||
Panel(
|
Panel(messages_table, title=lang["messages_tools"], border_style="blue")
|
||||||
messages_table,
|
|
||||||
title="Messages & Tools",
|
|
||||||
border_style="blue",
|
|
||||||
padding=(1, 2),
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Analysis panel showing current report
|
# Analysis panel showing current report
|
||||||
|
|
@ -359,7 +354,7 @@ def update_display(layout, spinner_text=None):
|
||||||
layout["analysis"].update(
|
layout["analysis"].update(
|
||||||
Panel(
|
Panel(
|
||||||
Markdown(message_buffer.current_report),
|
Markdown(message_buffer.current_report),
|
||||||
title="Current Report",
|
title=lang["current_report"],
|
||||||
border_style="green",
|
border_style="green",
|
||||||
padding=(1, 2),
|
padding=(1, 2),
|
||||||
)
|
)
|
||||||
|
|
@ -368,7 +363,7 @@ def update_display(layout, spinner_text=None):
|
||||||
layout["analysis"].update(
|
layout["analysis"].update(
|
||||||
Panel(
|
Panel(
|
||||||
"[italic]Waiting for analysis report...[/italic]",
|
"[italic]Waiting for analysis report...[/italic]",
|
||||||
title="Current Report",
|
title=lang["current_report"],
|
||||||
border_style="green",
|
border_style="green",
|
||||||
padding=(1, 2),
|
padding=(1, 2),
|
||||||
)
|
)
|
||||||
|
|
@ -400,9 +395,9 @@ def get_user_selections():
|
||||||
|
|
||||||
# Create welcome box content
|
# Create welcome box content
|
||||||
welcome_content = f"{welcome_ascii}\n"
|
welcome_content = f"{welcome_ascii}\n"
|
||||||
welcome_content += "[bold green]TradingAgents: Multi-Agents LLM Financial Trading Framework - CLI[/bold green]\n\n"
|
welcome_content += f"[bold green]TradingAgents: {lang['framework_subtitle']} - CLI[/bold green]\n\n"
|
||||||
welcome_content += "[bold]Workflow Steps:[/bold]\n"
|
welcome_content += f"[bold]{lang['workflow_steps_title']}[/bold]\n"
|
||||||
welcome_content += "I. Analyst Team → II. Research Team → III. Trader → IV. Risk Management → V. Portfolio Management\n\n"
|
welcome_content += lang['workflow_steps']
|
||||||
welcome_content += (
|
welcome_content += (
|
||||||
"[dim]Built by [Tauric Research](https://github.com/TauricResearch)[/dim]"
|
"[dim]Built by [Tauric Research](https://github.com/TauricResearch)[/dim]"
|
||||||
)
|
)
|
||||||
|
|
@ -412,8 +407,8 @@ def get_user_selections():
|
||||||
welcome_content,
|
welcome_content,
|
||||||
border_style="green",
|
border_style="green",
|
||||||
padding=(1, 2),
|
padding=(1, 2),
|
||||||
title="Welcome to TradingAgents",
|
title= lang["welcome"],
|
||||||
subtitle="Multi-Agents LLM Financial Trading Framework",
|
subtitle=lang["framework_subtitle"],
|
||||||
)
|
)
|
||||||
console.print(Align.center(welcome_box))
|
console.print(Align.center(welcome_box))
|
||||||
console.print() # Add a blank line after the welcome box
|
console.print() # Add a blank line after the welcome box
|
||||||
|
|
@ -429,7 +424,7 @@ def get_user_selections():
|
||||||
# Step 1: Ticker symbol
|
# Step 1: Ticker symbol
|
||||||
console.print(
|
console.print(
|
||||||
create_question_box(
|
create_question_box(
|
||||||
"Step 1: Ticker Symbol", "Enter the ticker symbol to analyze", "SPY"
|
lang["step1_title"], lang["step1_prompt"], lang["default_ticker"]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
selected_ticker = get_ticker()
|
selected_ticker = get_ticker()
|
||||||
|
|
@ -438,8 +433,8 @@ def get_user_selections():
|
||||||
default_date = datetime.datetime.now().strftime("%Y-%m-%d")
|
default_date = datetime.datetime.now().strftime("%Y-%m-%d")
|
||||||
console.print(
|
console.print(
|
||||||
create_question_box(
|
create_question_box(
|
||||||
"Step 2: Analysis Date",
|
lang["step2_title"],
|
||||||
"Enter the analysis date (YYYY-MM-DD)",
|
lang["step2_prompt"],
|
||||||
default_date,
|
default_date,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
@ -448,7 +443,7 @@ def get_user_selections():
|
||||||
# Step 3: Select analysts
|
# Step 3: Select analysts
|
||||||
console.print(
|
console.print(
|
||||||
create_question_box(
|
create_question_box(
|
||||||
"Step 3: Analysts Team", "Select your LLM analyst agents for the analysis"
|
lang["step3_title"], lang["step3_prompt"]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
selected_analysts = select_analysts()
|
selected_analysts = select_analysts()
|
||||||
|
|
@ -459,7 +454,7 @@ def get_user_selections():
|
||||||
# Step 4: Research depth
|
# Step 4: Research depth
|
||||||
console.print(
|
console.print(
|
||||||
create_question_box(
|
create_question_box(
|
||||||
"Step 4: Research Depth", "Select your research depth level"
|
lang["step4_title"], lang["step4_prompt"]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
selected_research_depth = select_research_depth()
|
selected_research_depth = select_research_depth()
|
||||||
|
|
@ -467,7 +462,7 @@ def get_user_selections():
|
||||||
# Step 5: OpenAI backend
|
# Step 5: OpenAI backend
|
||||||
console.print(
|
console.print(
|
||||||
create_question_box(
|
create_question_box(
|
||||||
"Step 5: OpenAI backend", "Select which service to talk to"
|
lang["step5_title"], lang["step5_prompt"]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
selected_llm_provider, backend_url = select_llm_provider()
|
selected_llm_provider, backend_url = select_llm_provider()
|
||||||
|
|
@ -475,7 +470,7 @@ def get_user_selections():
|
||||||
# Step 6: Thinking agents
|
# Step 6: Thinking agents
|
||||||
console.print(
|
console.print(
|
||||||
create_question_box(
|
create_question_box(
|
||||||
"Step 6: Thinking Agents", "Select your thinking agents for analysis"
|
lang["step6_title"], lang["step6_prompt"]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
selected_shallow_thinker = select_shallow_thinking_agent(selected_llm_provider)
|
selected_shallow_thinker = select_shallow_thinking_agent(selected_llm_provider)
|
||||||
|
|
|
||||||
30
cli/utils.py
30
cli/utils.py
|
|
@ -2,6 +2,9 @@ import questionary
|
||||||
from typing import List, Optional, Tuple, Dict
|
from typing import List, Optional, Tuple, Dict
|
||||||
|
|
||||||
from cli.models import AnalystType
|
from cli.models import AnalystType
|
||||||
|
from tradingagents.i18n import get_lang
|
||||||
|
|
||||||
|
lang = get_lang()
|
||||||
|
|
||||||
ANALYST_ORDER = [
|
ANALYST_ORDER = [
|
||||||
("Market Analyst", AnalystType.MARKET),
|
("Market Analyst", AnalystType.MARKET),
|
||||||
|
|
@ -14,8 +17,8 @@ ANALYST_ORDER = [
|
||||||
def get_ticker() -> str:
|
def get_ticker() -> str:
|
||||||
"""Prompt the user to enter a ticker symbol."""
|
"""Prompt the user to enter a ticker symbol."""
|
||||||
ticker = questionary.text(
|
ticker = questionary.text(
|
||||||
"Enter the ticker symbol to analyze:",
|
lang["step1_prompt"],
|
||||||
validate=lambda x: len(x.strip()) > 0 or "Please enter a valid ticker symbol.",
|
validate=lambda x: len(x.strip()) > 0 or lang["ticker_validate"],
|
||||||
style=questionary.Style(
|
style=questionary.Style(
|
||||||
[
|
[
|
||||||
("text", "fg:green"),
|
("text", "fg:green"),
|
||||||
|
|
@ -46,9 +49,8 @@ def get_analysis_date() -> str:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
date = questionary.text(
|
date = questionary.text(
|
||||||
"Enter the analysis date (YYYY-MM-DD):",
|
lang["step2_prompt"],
|
||||||
validate=lambda x: validate_date(x.strip())
|
validate=lambda x: validate_date(x.strip()) or lang["date_validate"],
|
||||||
or "Please enter a valid date in YYYY-MM-DD format.",
|
|
||||||
style=questionary.Style(
|
style=questionary.Style(
|
||||||
[
|
[
|
||||||
("text", "fg:green"),
|
("text", "fg:green"),
|
||||||
|
|
@ -67,12 +69,12 @@ def get_analysis_date() -> str:
|
||||||
def select_analysts() -> List[AnalystType]:
|
def select_analysts() -> List[AnalystType]:
|
||||||
"""Select analysts using an interactive checkbox."""
|
"""Select analysts using an interactive checkbox."""
|
||||||
choices = questionary.checkbox(
|
choices = questionary.checkbox(
|
||||||
"Select Your [Analysts Team]:",
|
lang["step3_prompt"],
|
||||||
choices=[
|
choices=[
|
||||||
questionary.Choice(display, value=value) for display, value in ANALYST_ORDER
|
questionary.Choice(lang.get(display.replace(" ", "_").lower(), display), value=value) for display, value in ANALYST_ORDER
|
||||||
],
|
],
|
||||||
instruction="\n- Press Space to select/unselect analysts\n- Press 'a' to select/unselect all\n- Press Enter when done",
|
instruction=lang["analyst_instruction"],
|
||||||
validate=lambda x: len(x) > 0 or "You must select at least one analyst.",
|
validate=lambda x: len(x) > 0 or lang["analyst_validate"],
|
||||||
style=questionary.Style(
|
style=questionary.Style(
|
||||||
[
|
[
|
||||||
("checkbox-selected", "fg:green"),
|
("checkbox-selected", "fg:green"),
|
||||||
|
|
@ -95,17 +97,17 @@ def select_research_depth() -> int:
|
||||||
|
|
||||||
# Define research depth options with their corresponding values
|
# Define research depth options with their corresponding values
|
||||||
DEPTH_OPTIONS = [
|
DEPTH_OPTIONS = [
|
||||||
("Shallow - Quick research, few debate and strategy discussion rounds", 1),
|
(lang["depth_shallow"], 1),
|
||||||
("Medium - Middle ground, moderate debate rounds and strategy discussion", 3),
|
(lang["depth_medium"], 3),
|
||||||
("Deep - Comprehensive research, in depth debate and strategy discussion", 5),
|
(lang["depth_deep"], 5),
|
||||||
]
|
]
|
||||||
|
|
||||||
choice = questionary.select(
|
choice = questionary.select(
|
||||||
"Select Your [Research Depth]:",
|
lang["step4_prompt"],
|
||||||
choices=[
|
choices=[
|
||||||
questionary.Choice(display, value=value) for display, value in DEPTH_OPTIONS
|
questionary.Choice(display, value=value) for display, value in DEPTH_OPTIONS
|
||||||
],
|
],
|
||||||
instruction="\n- Use arrow keys to navigate\n- Press Enter to select",
|
instruction=lang["depth_instruction"],
|
||||||
style=questionary.Style(
|
style=questionary.Style(
|
||||||
[
|
[
|
||||||
("selected", "fg:yellow noinherit"),
|
("selected", "fg:yellow noinherit"),
|
||||||
|
|
|
||||||
|
|
@ -19,4 +19,6 @@ DEFAULT_CONFIG = {
|
||||||
"max_recur_limit": 100,
|
"max_recur_limit": 100,
|
||||||
# Tool settings
|
# Tool settings
|
||||||
"online_tools": True,
|
"online_tools": True,
|
||||||
|
# Language settings
|
||||||
|
"language": "zh", # 支持 'zh' 或 'en'
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
import importlib
|
||||||
|
from tradingagents.default_config import DEFAULT_CONFIG
|
||||||
|
|
||||||
|
def get_lang():
|
||||||
|
lang_code = DEFAULT_CONFIG.get("language", "zh")
|
||||||
|
try:
|
||||||
|
lang_module = importlib.import_module(f"tradingagents.i18n.{lang_code}")
|
||||||
|
return lang_module.LANG
|
||||||
|
except Exception:
|
||||||
|
# fallback to zh
|
||||||
|
from .zh import LANG
|
||||||
|
return LANG
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
LANG = {
|
||||||
|
"welcome": "Welcome to TradingAgents CLI",
|
||||||
|
"analyst_team": "Analyst Team",
|
||||||
|
"market_analyst": "Market Analyst",
|
||||||
|
"social_analyst": "Social Analyst",
|
||||||
|
"news_analyst": "News Analyst",
|
||||||
|
"social_media_analyst": "Social Media Analyst",
|
||||||
|
"fundamentals_analyst": "Fundamentals Analyst",
|
||||||
|
"research_team": "Research Team",
|
||||||
|
"bull_researcher": "Bull Researcher",
|
||||||
|
"bear_researcher": "Bear Researcher",
|
||||||
|
"research_manager": "Research Manager",
|
||||||
|
"trading_team": "Trading Team",
|
||||||
|
"trader": "Trader",
|
||||||
|
"risk_management": "Risk Management",
|
||||||
|
"risky_analyst": "Risky Analyst",
|
||||||
|
"neutral_analyst": "Neutral Analyst",
|
||||||
|
"safe_analyst": "Safe Analyst",
|
||||||
|
"portfolio_management": "Portfolio Management",
|
||||||
|
"portfolio_manager": "Portfolio Manager",
|
||||||
|
"market_report": "Market Report",
|
||||||
|
"sentiment_report": "Sentiment Report",
|
||||||
|
"news_report": "News Report",
|
||||||
|
"fundamentals_report": "Fundamentals Report",
|
||||||
|
"investment_plan": "Investment Plan",
|
||||||
|
"trader_investment_plan": "Trader Investment Plan",
|
||||||
|
"final_trade_decision": "Final Trade Decision",
|
||||||
|
"team": "Team",
|
||||||
|
"agent": "Agent",
|
||||||
|
"status": "Status",
|
||||||
|
"progress": "Progress",
|
||||||
|
"messages_tools": "Messages & Tools",
|
||||||
|
"current_report": "Current Report",
|
||||||
|
"pending": "Pending",
|
||||||
|
"completed": "Completed",
|
||||||
|
"error": "Error",
|
||||||
|
"in_progress": "In Progress",
|
||||||
|
"time": "Time",
|
||||||
|
"type": "Type",
|
||||||
|
"content": "Content",
|
||||||
|
"tool": "Tool",
|
||||||
|
"spinner": "Loading",
|
||||||
|
"framework_subtitle": "Multi-Agents LLM Financial Trading Framework",
|
||||||
|
"workflow_steps_title": "Workflow Steps:",
|
||||||
|
"workflow_steps": "I. Analyst Team → II. Research Team → III. Trader → IV. Risk Management → V. Portfolio Management\n\n",
|
||||||
|
"step1_title": "Step 1: Ticker Symbol",
|
||||||
|
"step1_prompt": "Enter the ticker symbol to analyze",
|
||||||
|
"step2_title": "Step 2: Analysis Date",
|
||||||
|
"step2_prompt": "Enter the analysis date (YYYY-MM-DD)",
|
||||||
|
"step3_title": "Step 3: Analysts Team",
|
||||||
|
"step3_prompt": "Select your LLM analyst agents for the analysis",
|
||||||
|
"step4_title": "Step 4: Research Depth",
|
||||||
|
"step4_prompt": "Select your research depth level",
|
||||||
|
"step5_title": "Step 5: Thinking Agents",
|
||||||
|
"step5_prompt": "Select your thinking agents for analysis",
|
||||||
|
"step6_title": "Step 6: Thinking Agents",
|
||||||
|
"step6_prompt": "Select your thinking agents for analysis",
|
||||||
|
"default_ticker": "SPY",
|
||||||
|
"ticker_validate": "Please enter a valid ticker symbol.",
|
||||||
|
"date_validate": "Please enter a valid date in YYYY-MM-DD format.",
|
||||||
|
"analyst_instruction": "\n- Press Space to select/unselect analysts\n- Press 'a' to select/unselect all\n- Press Enter when done",
|
||||||
|
"analyst_validate": "You must select at least one analyst.",
|
||||||
|
"depth_shallow": "Shallow - Quick research, few debate and strategy discussion rounds",
|
||||||
|
"depth_medium": "Medium - Middle ground, moderate debate rounds and strategy discussion",
|
||||||
|
"depth_deep": "Deep - Comprehensive research, in depth debate and strategy discussion",
|
||||||
|
"depth_instruction": "\n- Use arrow keys to navigate\n- Press Enter to select",
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
LANG = {
|
||||||
|
"welcome": "欢迎使用TradingAgents CLI",
|
||||||
|
"analyst_team": "分析师团队",
|
||||||
|
"market_analyst": "市场分析师",
|
||||||
|
"social_media_analyst": "社会媒体分析师",
|
||||||
|
"social_analyst": "社交分析师",
|
||||||
|
"news_analyst": "新闻分析师",
|
||||||
|
"fundamentals_analyst": "基本面分析师",
|
||||||
|
"research_team": "研究团队",
|
||||||
|
"bull_researcher": "多头研究员",
|
||||||
|
"bear_researcher": "空头研究员",
|
||||||
|
"research_manager": "研究经理",
|
||||||
|
"trading_team": "交易团队",
|
||||||
|
"trader": "交易员",
|
||||||
|
"risk_management": "风险管理",
|
||||||
|
"risky_analyst": "激进分析师",
|
||||||
|
"neutral_analyst": "中性分析师",
|
||||||
|
"safe_analyst": "保守分析师",
|
||||||
|
"portfolio_management": "投资组合管理",
|
||||||
|
"portfolio_manager": "投资组合经理",
|
||||||
|
"market_report": "市场分析报告",
|
||||||
|
"sentiment_report": "情绪分析报告",
|
||||||
|
"news_report": "新闻分析报告",
|
||||||
|
"fundamentals_report": "基本面分析报告",
|
||||||
|
"investment_plan": "投资计划",
|
||||||
|
"trader_investment_plan": "交易员投资计划",
|
||||||
|
"final_trade_decision": "最终交易决策",
|
||||||
|
"team": "团队",
|
||||||
|
"agent": "代理人",
|
||||||
|
"status": "状态",
|
||||||
|
"progress": "进度",
|
||||||
|
"messages_tools": "消息与工具",
|
||||||
|
"current_report": "当前报告",
|
||||||
|
"pending": "待处理",
|
||||||
|
"completed": "已完成",
|
||||||
|
"error": "错误",
|
||||||
|
"in_progress": "进行中",
|
||||||
|
"time": "时间",
|
||||||
|
"type": "类型",
|
||||||
|
"content": "内容",
|
||||||
|
"tool": "工具",
|
||||||
|
"spinner": "加载中",
|
||||||
|
"framework_subtitle": "多智能体大模型金融交易框架",
|
||||||
|
"workflow_steps_title": "工作流步骤:",
|
||||||
|
"workflow_steps": "I. 分析师团队 → II. 研究团队 → III. 交易员 → IV. 风险管理 → V. 投资组合管理\n\n",
|
||||||
|
"step1_title": "步骤1:股票代码",
|
||||||
|
"step1_prompt": "请输入要分析的股票代码",
|
||||||
|
"step2_title": "步骤2:分析日期",
|
||||||
|
"step2_prompt": "请输入分析日期(YYYY-MM-DD)",
|
||||||
|
"step3_title": "步骤3:分析师团队",
|
||||||
|
"step3_prompt": "请选择用于分析的LLM分析师代理",
|
||||||
|
"step4_title": "步骤4:研究深度",
|
||||||
|
"step4_prompt": "请选择研究深度等级",
|
||||||
|
"step5_title": "步骤5:思考代理",
|
||||||
|
"step5_prompt": "请选择用于分析的思考代理",
|
||||||
|
"step6_title": "步骤6:思考代理",
|
||||||
|
"step6_prompt": "请选择用于分析的思考代理",
|
||||||
|
"default_ticker": "SPY",
|
||||||
|
"ticker_validate": "请输入有效的股票代码。",
|
||||||
|
"date_validate": "请输入有效的日期,格式为YYYY-MM-DD。",
|
||||||
|
"analyst_instruction": "\n- 空格选择/取消分析师\n- 'a' 全选/取消全选\n- 回车确认",
|
||||||
|
"analyst_validate": "请至少选择一位分析师。",
|
||||||
|
"depth_shallow": "浅层 - 快速研究,少量辩论与策略讨论轮次",
|
||||||
|
"depth_medium": "中等 - 适中研究,适量辩论与策略讨论",
|
||||||
|
"depth_deep": "深度 - 全面研究,深入辩论与策略讨论",
|
||||||
|
"depth_instruction": "\n- 使用方向键选择\n- 回车确认",
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue