rename reports

This commit is contained in:
Jeffrey Chu 2025-10-24 00:07:04 +08:00
parent 477a2570c6
commit e6a18061a1
17 changed files with 184 additions and 181 deletions

View File

@ -1,16 +1,15 @@
from typing import Optional
import datetime import datetime
import typer
from pathlib import Path
from functools import wraps from functools import wraps
from rich.console import Console from pathlib import Path
import typer
from dotenv import load_dotenv from dotenv import load_dotenv
from rich.console import Console
# Load environment variables from .env file # Load environment variables from .env file
load_dotenv() load_dotenv()
from rich.panel import Panel from rich.panel import Panel
from rich.spinner import Spinner from rich.spinner import Spinner
from rich.live import Live
from rich.columns import Columns from rich.columns import Columns
from rich.markdown import Markdown from rich.markdown import Markdown
from rich.layout import Layout from rich.layout import Layout
@ -18,15 +17,11 @@ from rich.text import Text
from rich.live import Live from rich.live import Live
from rich.table import Table from rich.table import Table
from collections import deque from collections import deque
import time
from rich.tree import Tree
from rich import box from rich import box
from rich.align import Align from rich.align import Align
from rich.rule import Rule
from tradingagents.graph.trading_graph import TradingAgentsGraph 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.utils import * from cli.utils import *
console = Console() console = Console()
@ -66,13 +61,13 @@ class MessageBuffer:
} }
self.current_agent = None self.current_agent = None
self.report_sections = { self.report_sections = {
"market_report": None, "market_analysis": None,
"sentiment_report": None, "sentiment_analysis": None,
"news_report": None, "news_analysis": None,
"fundamentals_report": None, "fundamentals_analysis": None,
"investment_plan": None, "research_team_decision": None,
"trader_investment_plan": None, "trader_team_plan": None,
"final_trade_decision": None, "final_portfolio_management_decision": None,
} }
def add_message(self, message_type, content): def add_message(self, message_type, content):
@ -107,13 +102,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_analysis": "Market Analysis",
"sentiment_report": "Social Sentiment", "sentiment_analysis": "Social Sentiment",
"news_report": "News Analysis", "news_analysis": "News Analysis",
"fundamentals_report": "Fundamentals Analysis", "fundamentals_analysis": "Fundamentals Analysis",
"investment_plan": "Research Team Decision", "research_team_decision": "Research Team Decision",
"trader_investment_plan": "Trading Team Plan", "trader_team_plan": "Trading Team Plan",
"final_trade_decision": "Portfolio Management Decision", "final_portfolio_management_decision": "Portfolio Management Decision",
} }
self.current_report = ( self.current_report = (
f"### {section_titles[latest_section]}\n{latest_content}" f"### {section_titles[latest_section]}\n{latest_content}"
@ -127,46 +122,46 @@ class MessageBuffer:
# Analyst Team Reports # Analyst Team Reports
if any( if any(
self.report_sections[section] self.report_sections[section]
for section in [ for section in [
"market_report", "market_analysis",
"sentiment_report", "sentiment_analysis",
"news_report", "news_analysis",
"fundamentals_report", "fundamentals_analysis",
] ]
): ):
report_parts.append("## Analyst Team Reports") report_parts.append("## Analyst Team Reports")
if self.report_sections["market_report"]: if self.report_sections["market_analysis"]:
report_parts.append( report_parts.append(
f"### Market Analysis\n{self.report_sections['market_report']}" f"### Market Analysis\n{self.report_sections['market_analysis']}"
) )
if self.report_sections["sentiment_report"]: if self.report_sections["sentiment_analysis"]:
report_parts.append( report_parts.append(
f"### Social Sentiment\n{self.report_sections['sentiment_report']}" f"### Social Sentiment\n{self.report_sections['sentiment_analysis']}"
) )
if self.report_sections["news_report"]: if self.report_sections["news_analysis"]:
report_parts.append( report_parts.append(
f"### News Analysis\n{self.report_sections['news_report']}" f"### News Analysis\n{self.report_sections['news_analysis']}"
) )
if self.report_sections["fundamentals_report"]: if self.report_sections["fundamentals_analysis"]:
report_parts.append( report_parts.append(
f"### Fundamentals Analysis\n{self.report_sections['fundamentals_report']}" f"### Fundamentals Analysis\n{self.report_sections['fundamentals_analysis']}"
) )
# Research Team Reports # Research Team Reports
if self.report_sections["investment_plan"]: if self.report_sections["research_team_decision"]:
report_parts.append("## Research Team Decision") report_parts.append("## Research Team Decision")
report_parts.append(f"{self.report_sections['investment_plan']}") report_parts.append(f"{self.report_sections['research_team_decision']}")
# Trading Team Reports # Trading Team Reports
if self.report_sections["trader_investment_plan"]: if self.report_sections["trader_team_plan"]:
report_parts.append("## Trading Team Plan") report_parts.append("## Trading Team Plan")
report_parts.append(f"{self.report_sections['trader_investment_plan']}") report_parts.append(f"{self.report_sections['trader_team_plan']}")
# Portfolio Management Decision # Portfolio Management Decision
if self.report_sections["final_trade_decision"]: if self.report_sections["final_portfolio_management_decision"]:
report_parts.append("## Portfolio Management Decision") report_parts.append("## Portfolio Management Decision")
report_parts.append(f"{self.report_sections['final_trade_decision']}") report_parts.append(f"{self.report_sections['final_portfolio_management_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
@ -537,10 +532,10 @@ def display_complete_report(final_state):
analyst_reports = [] analyst_reports = []
# Market Analyst Report # Market Analyst Report
if final_state.get("market_report"): if final_state.get("market_analysis"):
analyst_reports.append( analyst_reports.append(
Panel( Panel(
Markdown(final_state["market_report"]), Markdown(final_state["market_analysis"]),
title="Market Analyst", title="Market Analyst",
border_style="blue", border_style="blue",
padding=(1, 2), padding=(1, 2),
@ -548,10 +543,10 @@ def display_complete_report(final_state):
) )
# Social Analyst Report # Social Analyst Report
if final_state.get("sentiment_report"): if final_state.get("sentiment_analysis"):
analyst_reports.append( analyst_reports.append(
Panel( Panel(
Markdown(final_state["sentiment_report"]), Markdown(final_state["sentiment_analysis"]),
title="Social Analyst", title="Social Analyst",
border_style="blue", border_style="blue",
padding=(1, 2), padding=(1, 2),
@ -559,10 +554,10 @@ def display_complete_report(final_state):
) )
# News Analyst Report # News Analyst Report
if final_state.get("news_report"): if final_state.get("news_analysis"):
analyst_reports.append( analyst_reports.append(
Panel( Panel(
Markdown(final_state["news_report"]), Markdown(final_state["news_analysis"]),
title="News Analyst", title="News Analyst",
border_style="blue", border_style="blue",
padding=(1, 2), padding=(1, 2),
@ -570,10 +565,10 @@ def display_complete_report(final_state):
) )
# Fundamentals Analyst Report # Fundamentals Analyst Report
if final_state.get("fundamentals_report"): if final_state.get("fundamentals_analysis"):
analyst_reports.append( analyst_reports.append(
Panel( Panel(
Markdown(final_state["fundamentals_report"]), Markdown(final_state["fundamentals_analysis"]),
title="Fundamentals Analyst", title="Fundamentals Analyst",
border_style="blue", border_style="blue",
padding=(1, 2), padding=(1, 2),
@ -639,11 +634,11 @@ def display_complete_report(final_state):
) )
# III. Trading Team Reports # III. Trading Team Reports
if final_state.get("trader_investment_plan"): if final_state.get("trader_team_plan"):
console.print( console.print(
Panel( Panel(
Panel( Panel(
Markdown(final_state["trader_investment_plan"]), Markdown(final_state["trader_team_plan"]),
title="Trader", title="Trader",
border_style="blue", border_style="blue",
padding=(1, 2), padding=(1, 2),
@ -725,6 +720,7 @@ 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): def extract_content_string(content):
"""Extract string content from various message formats.""" """Extract string content from various message formats."""
if isinstance(content, str): if isinstance(content, str):
@ -744,6 +740,7 @@ def extract_content_string(content):
else: else:
return str(content) return str(content)
def run_analysis(): def run_analysis():
# First get all user selections # First get all user selections
selections = get_user_selections() selections = get_user_selections()
@ -773,6 +770,7 @@ def run_analysis():
def save_message_decorator(obj, func_name): def save_message_decorator(obj, func_name):
func = getattr(obj, func_name) func = getattr(obj, func_name)
@wraps(func) @wraps(func)
def wrapper(*args, **kwargs): def wrapper(*args, **kwargs):
func(*args, **kwargs) func(*args, **kwargs)
@ -780,10 +778,12 @@ def run_analysis():
content = content.replace("\n", " ") # Replace newlines with spaces content = content.replace("\n", " ") # Replace newlines with spaces
with open(log_file, "a") as f: with open(log_file, "a") as f:
f.write(f"{timestamp} [{message_type}] {content}\n") f.write(f"{timestamp} [{message_type}] {content}\n")
return wrapper return wrapper
def save_tool_call_decorator(obj, func_name): def save_tool_call_decorator(obj, func_name):
func = getattr(obj, func_name) func = getattr(obj, func_name)
@wraps(func) @wraps(func)
def wrapper(*args, **kwargs): def wrapper(*args, **kwargs):
func(*args, **kwargs) func(*args, **kwargs)
@ -791,10 +791,12 @@ def run_analysis():
args_str = ", ".join(f"{k}={v}" for k, v in args.items()) args_str = ", ".join(f"{k}={v}" for k, v in args.items())
with open(log_file, "a") as f: with open(log_file, "a") as f:
f.write(f"{timestamp} [Tool Call] {tool_name}({args_str})\n") f.write(f"{timestamp} [Tool Call] {tool_name}({args_str})\n")
return wrapper return wrapper
def save_report_section_decorator(obj, func_name): def save_report_section_decorator(obj, func_name):
func = getattr(obj, func_name) func = getattr(obj, func_name)
@wraps(func) @wraps(func)
def wrapper(section_name, content): def wrapper(section_name, content):
func(section_name, content) func(section_name, content)
@ -804,6 +806,7 @@ def run_analysis():
file_name = f"{section_name}.md" file_name = f"{section_name}.md"
with open(report_dir / file_name, "w") as f: with open(report_dir / file_name, "w") as f:
f.write(content) f.write(content)
return wrapper return wrapper
message_buffer.add_message = save_message_decorator(message_buffer, "add_message") message_buffer.add_message = save_message_decorator(message_buffer, "add_message")
@ -886,9 +889,9 @@ def run_analysis():
# Update reports and agent status based on chunk content # Update reports and agent status based on chunk content
# Analyst Team Reports # Analyst Team Reports
if "market_report" in chunk and chunk["market_report"]: if "market_analysis" in chunk and chunk["market_analysis"]:
message_buffer.update_report_section( message_buffer.update_report_section(
"market_report", chunk["market_report"] "market_analysis", chunk["market_analysis"]
) )
message_buffer.update_agent_status("Market Analyst", "completed") message_buffer.update_agent_status("Market Analyst", "completed")
# Set next analyst to in_progress # Set next analyst to in_progress
@ -897,9 +900,9 @@ def run_analysis():
"Social Analyst", "in_progress" "Social Analyst", "in_progress"
) )
if "sentiment_report" in chunk and chunk["sentiment_report"]: if "sentiment_analysis" in chunk and chunk["sentiment_analysis"]:
message_buffer.update_report_section( message_buffer.update_report_section(
"sentiment_report", chunk["sentiment_report"] "sentiment_analysis", chunk["sentiment_analysis"]
) )
message_buffer.update_agent_status("Social Analyst", "completed") message_buffer.update_agent_status("Social Analyst", "completed")
# Set next analyst to in_progress # Set next analyst to in_progress
@ -908,9 +911,9 @@ def run_analysis():
"News Analyst", "in_progress" "News Analyst", "in_progress"
) )
if "news_report" in chunk and chunk["news_report"]: if "news_analysis" in chunk and chunk["news_analysis"]:
message_buffer.update_report_section( message_buffer.update_report_section(
"news_report", chunk["news_report"] "news_analysis", chunk["news_analysis"]
) )
message_buffer.update_agent_status("News Analyst", "completed") message_buffer.update_agent_status("News Analyst", "completed")
# Set next analyst to in_progress # Set next analyst to in_progress
@ -919,9 +922,9 @@ def run_analysis():
"Fundamentals Analyst", "in_progress" "Fundamentals Analyst", "in_progress"
) )
if "fundamentals_report" in chunk and chunk["fundamentals_report"]: if "fundamentals_analysis" in chunk and chunk["fundamentals_analysis"]:
message_buffer.update_report_section( message_buffer.update_report_section(
"fundamentals_report", chunk["fundamentals_report"] "fundamentals_analysis", chunk["fundamentals_analysis"]
) )
message_buffer.update_agent_status( message_buffer.update_agent_status(
"Fundamentals Analyst", "completed" "Fundamentals Analyst", "completed"
@ -931,8 +934,8 @@ def run_analysis():
# Research Team - Handle Investment Debate State # Research Team - Handle Investment Debate State
if ( if (
"investment_debate_state" in chunk "investment_debate_state" in chunk
and chunk["investment_debate_state"] and chunk["investment_debate_state"]
): ):
debate_state = chunk["investment_debate_state"] debate_state = chunk["investment_debate_state"]
@ -947,7 +950,7 @@ def run_analysis():
message_buffer.add_message("Reasoning", latest_bull) message_buffer.add_message("Reasoning", latest_bull)
# Update research report with bull's latest analysis # Update research report with bull's latest analysis
message_buffer.update_report_section( message_buffer.update_report_section(
"investment_plan", "research_team_decision",
f"### Bull Researcher Analysis\n{latest_bull}", f"### Bull Researcher Analysis\n{latest_bull}",
) )
@ -962,14 +965,14 @@ def run_analysis():
message_buffer.add_message("Reasoning", latest_bear) message_buffer.add_message("Reasoning", latest_bear)
# Update research report with bear's latest analysis # Update research report with bear's latest analysis
message_buffer.update_report_section( message_buffer.update_report_section(
"investment_plan", "research_team_decision",
f"{message_buffer.report_sections['investment_plan']}\n\n### Bear Researcher Analysis\n{latest_bear}", f"{message_buffer.report_sections['research_team_decision']}\n\n### Bear Researcher Analysis\n{latest_bear}",
) )
# Update Research Manager status and final decision # Update Research Manager status and final decision
if ( if (
"judge_decision" in debate_state "judge_decision" in debate_state
and debate_state["judge_decision"] and debate_state["judge_decision"]
): ):
# Keep all research team members in progress until final decision # Keep all research team members in progress until final decision
update_research_team_status("in_progress") update_research_team_status("in_progress")
@ -979,8 +982,8 @@ def run_analysis():
) )
# Update research report with final decision # Update research report with final decision
message_buffer.update_report_section( message_buffer.update_report_section(
"investment_plan", "research_team_decision",
f"{message_buffer.report_sections['investment_plan']}\n\n### Research Manager Decision\n{debate_state['judge_decision']}", f"{message_buffer.report_sections['research_team_decision']}\n\n### Research Manager Decision\n{debate_state['judge_decision']}",
) )
# Mark all research team members as completed # Mark all research team members as completed
update_research_team_status("completed") update_research_team_status("completed")
@ -991,11 +994,11 @@ def run_analysis():
# Trading Team # Trading Team
if ( if (
"trader_investment_plan" in chunk "trader_team_plan" in chunk
and chunk["trader_investment_plan"] and chunk["trader_team_plan"]
): ):
message_buffer.update_report_section( message_buffer.update_report_section(
"trader_investment_plan", chunk["trader_investment_plan"] "trader_team_plan", chunk["trader_team_plan"]
) )
# Set first risk analyst to in_progress # Set first risk analyst to in_progress
message_buffer.update_agent_status("Risky Analyst", "in_progress") message_buffer.update_agent_status("Risky Analyst", "in_progress")
@ -1006,8 +1009,8 @@ def run_analysis():
# Update Risky Analyst status and report # Update Risky Analyst status and report
if ( if (
"current_risky_response" in risk_state "current_risky_response" in risk_state
and risk_state["current_risky_response"] and risk_state["current_risky_response"]
): ):
message_buffer.update_agent_status( message_buffer.update_agent_status(
"Risky Analyst", "in_progress" "Risky Analyst", "in_progress"
@ -1018,14 +1021,14 @@ def run_analysis():
) )
# Update risk report with risky analyst's latest analysis only # Update risk report with risky analyst's latest analysis only
message_buffer.update_report_section( message_buffer.update_report_section(
"final_trade_decision", "final_portfolio_management_decision",
f"### Risky Analyst Analysis\n{risk_state['current_risky_response']}", f"### Risky Analyst Analysis\n{risk_state['current_risky_response']}",
) )
# Update Safe Analyst status and report # Update Safe Analyst status and report
if ( if (
"current_safe_response" in risk_state "current_safe_response" in risk_state
and risk_state["current_safe_response"] and risk_state["current_safe_response"]
): ):
message_buffer.update_agent_status( message_buffer.update_agent_status(
"Safe Analyst", "in_progress" "Safe Analyst", "in_progress"
@ -1036,14 +1039,14 @@ def run_analysis():
) )
# Update risk report with safe analyst's latest analysis only # Update risk report with safe analyst's latest analysis only
message_buffer.update_report_section( message_buffer.update_report_section(
"final_trade_decision", "final_portfolio_management_decision",
f"### Safe Analyst Analysis\n{risk_state['current_safe_response']}", f"### Safe Analyst Analysis\n{risk_state['current_safe_response']}",
) )
# Update Neutral Analyst status and report # Update Neutral Analyst status and report
if ( if (
"current_neutral_response" in risk_state "current_neutral_response" in risk_state
and risk_state["current_neutral_response"] and risk_state["current_neutral_response"]
): ):
message_buffer.update_agent_status( message_buffer.update_agent_status(
"Neutral Analyst", "in_progress" "Neutral Analyst", "in_progress"
@ -1054,7 +1057,7 @@ def run_analysis():
) )
# Update risk report with neutral analyst's latest analysis only # Update risk report with neutral analyst's latest analysis only
message_buffer.update_report_section( message_buffer.update_report_section(
"final_trade_decision", "final_portfolio_management_decision",
f"### Neutral Analyst Analysis\n{risk_state['current_neutral_response']}", f"### Neutral Analyst Analysis\n{risk_state['current_neutral_response']}",
) )
@ -1069,7 +1072,7 @@ def run_analysis():
) )
# Update risk report with final decision only # Update risk report with final decision only
message_buffer.update_report_section( message_buffer.update_report_section(
"final_trade_decision", "final_portfolio_management_decision",
f"### Portfolio Manager Decision\n{risk_state['judge_decision']}", f"### Portfolio Manager Decision\n{risk_state['judge_decision']}",
) )
# Mark risk analysts as completed # Mark risk analysts as completed
@ -1089,7 +1092,7 @@ def run_analysis():
# Get final state and decision # Get final state and decision
final_state = trace[-1] final_state = trace[-1]
decision = graph.process_signal(final_state["final_trade_decision"]) decision = graph.process_signal(final_state["final_portfolio_management_decision"])
# Update all agent statuses to completed # Update all agent statuses to completed
for agent in message_buffer.agent_status: for agent in message_buffer.agent_status:

View File

@ -73,7 +73,7 @@ Output language: ***{language_prompt}***
return { return {
"messages": [result], "messages": [result],
"fundamentals_report": report, "fundamentals_analysis": report,
} }
return fundamentals_analyst_node return fundamentals_analyst_node

View File

@ -90,7 +90,7 @@ Output language: ***{language_prompt}***
return { return {
"messages": [result], "messages": [result],
"market_report": report, "market_analysis": report,
} }
return market_analyst_node return market_analyst_node

View File

@ -67,7 +67,7 @@ Output language: ***{language_prompt}***
return { return {
"messages": [result], "messages": [result],
"news_report": report, "news_analysis": report,
} }
return news_analyst_node return news_analyst_node

View File

@ -68,7 +68,7 @@ Output language: ***{language_prompt}***
return { return {
"messages": [result], "messages": [result],
"sentiment_report": report, "sentiment_analysis": report,
} }
return social_media_analyst_node return social_media_analyst_node

View File

@ -10,14 +10,14 @@ def create_research_manager(llm, memory, config):
def research_manager_node(state) -> dict: def research_manager_node(state) -> dict:
history = state["investment_debate_state"].get("history", "") history = state["investment_debate_state"].get("history", "")
market_research_report = state["market_report"] market_research_report = state["market_analysis"]
sentiment_report = state["sentiment_report"] sentiment_analysis = state["sentiment_analysis"]
news_report = state["news_report"] news_analysis = state["news_analysis"]
fundamentals_report = state["fundamentals_report"] fundamentals_analysis = state["fundamentals_analysis"]
investment_debate_state = state["investment_debate_state"] investment_debate_state = state["investment_debate_state"]
curr_situation = f"{market_research_report}\n\n{sentiment_report}\n\n{news_report}\n\n{fundamentals_report}" curr_situation = f"{market_research_report}\n\n{sentiment_analysis}\n\n{news_analysis}\n\n{fundamentals_analysis}"
past_memories = memory.get_memories(curr_situation, n_matches=2) past_memories = memory.get_memories(curr_situation, n_matches=2)
past_memory_str = "" past_memory_str = ""
@ -56,7 +56,7 @@ Output language: ***{language_prompt}***
return { return {
"investment_debate_state": new_investment_debate_state, "investment_debate_state": new_investment_debate_state,
"investment_plan": response.content, "research_team_decision": response.content,
} }
return research_manager_node return research_manager_node

View File

@ -13,13 +13,13 @@ def create_risk_manager(llm, memory, config):
history = state["risk_debate_state"]["history"] history = state["risk_debate_state"]["history"]
risk_debate_state = state["risk_debate_state"] risk_debate_state = state["risk_debate_state"]
market_research_report = state["market_report"] market_research_report = state["market_analysis"]
news_report = state["news_report"] news_analysis = state["news_analysis"]
fundamentals_report = state["news_report"] fundamentals_analysis = state["news_analysis"]
sentiment_report = state["sentiment_report"] sentiment_analysis = state["sentiment_analysis"]
trader_plan = state["investment_plan"] trader_plan = state["research_team_decision"]
curr_situation = f"{market_research_report}\n\n{sentiment_report}\n\n{news_report}\n\n{fundamentals_report}" curr_situation = f"{market_research_report}\n\n{sentiment_analysis}\n\n{news_analysis}\n\n{fundamentals_analysis}"
past_memories = memory.get_memories(curr_situation, n_matches=2) past_memories = memory.get_memories(curr_situation, n_matches=2)
past_memory_str = "" past_memory_str = ""
@ -68,7 +68,7 @@ Output language: ***{language_prompt}***
return { return {
"risk_debate_state": new_risk_debate_state, "risk_debate_state": new_risk_debate_state,
"final_trade_decision": response.content, "final_portfolio_management_decision": response.content,
} }
return risk_manager_node return risk_manager_node

View File

@ -14,12 +14,12 @@ def create_bear_researcher(llm, memory, config):
bear_history = investment_debate_state.get("bear_history", "") bear_history = investment_debate_state.get("bear_history", "")
current_response = investment_debate_state.get("current_response", "") current_response = investment_debate_state.get("current_response", "")
market_research_report = state["market_report"] market_research_report = state["market_analysis"]
sentiment_report = state["sentiment_report"] sentiment_analysis = state["sentiment_analysis"]
news_report = state["news_report"] news_analysis = state["news_analysis"]
fundamentals_report = state["fundamentals_report"] fundamentals_analysis = state["fundamentals_analysis"]
curr_situation = f"{market_research_report}\n\n{sentiment_report}\n\n{news_report}\n\n{fundamentals_report}" curr_situation = f"{market_research_report}\n\n{sentiment_analysis}\n\n{news_analysis}\n\n{fundamentals_analysis}"
past_memories = memory.get_memories(curr_situation, n_matches=2) past_memories = memory.get_memories(curr_situation, n_matches=2)
past_memory_str = "" past_memory_str = ""
@ -46,17 +46,17 @@ Market research report:
-------------------------------------- --------------------------------------
Social media sentiment report: Social media sentiment report:
{sentiment_report} {sentiment_analysis}
-------------------------------------- --------------------------------------
Latest world affairs news: Latest world affairs news:
{news_report} {news_analysis}
-------------------------------------- --------------------------------------
Company fundamentals report: Company fundamentals report:
{fundamentals_report} {fundamentals_analysis}
-------------------------------------- --------------------------------------

View File

@ -14,12 +14,12 @@ def create_bull_researcher(llm, memory, config):
bull_history = investment_debate_state.get("bull_history", "") bull_history = investment_debate_state.get("bull_history", "")
current_response = investment_debate_state.get("current_response", "") current_response = investment_debate_state.get("current_response", "")
market_research_report = state["market_report"] market_research_report = state["market_analysis"]
sentiment_report = state["sentiment_report"] sentiment_analysis = state["sentiment_analysis"]
news_report = state["news_report"] news_analysis = state["news_analysis"]
fundamentals_report = state["fundamentals_report"] fundamentals_analysis = state["fundamentals_analysis"]
curr_situation = f"{market_research_report}\n\n{sentiment_report}\n\n{news_report}\n\n{fundamentals_report}" curr_situation = f"{market_research_report}\n\n{sentiment_analysis}\n\n{news_analysis}\n\n{fundamentals_analysis}"
past_memories = memory.get_memories(curr_situation, n_matches=2) past_memories = memory.get_memories(curr_situation, n_matches=2)
past_memory_str = "" past_memory_str = ""
@ -44,17 +44,17 @@ Market research report:
-------------------------------------- --------------------------------------
Social media sentiment report: Social media sentiment report:
{sentiment_report} {sentiment_analysis}
-------------------------------------- --------------------------------------
Latest world affairs news: Latest world affairs news:
{news_report} {news_analysis}
-------------------------------------- --------------------------------------
Company fundamentals report: Company fundamentals report:
{fundamentals_report} {fundamentals_analysis}
-------------------------------------- --------------------------------------

View File

@ -16,12 +16,12 @@ def create_risky_debator(llm, config):
current_safe_response = risk_debate_state.get("current_safe_response", "") current_safe_response = risk_debate_state.get("current_safe_response", "")
current_neutral_response = risk_debate_state.get("current_neutral_response", "") current_neutral_response = risk_debate_state.get("current_neutral_response", "")
market_research_report = state["market_report"] market_research_report = state["market_analysis"]
sentiment_report = state["sentiment_report"] sentiment_analysis = state["sentiment_analysis"]
news_report = state["news_report"] news_analysis = state["news_analysis"]
fundamentals_report = state["fundamentals_report"] fundamentals_analysis = state["fundamentals_analysis"]
trader_decision = state["trader_investment_plan"] trader_decision = state["trader_team_plan"]
prompt = f""" prompt = f"""
As the Risky Risk Analyst, your role is to actively champion high-reward, high-risk opportunities, emphasizing bold strategies and competitive advantages. As the Risky Risk Analyst, your role is to actively champion high-reward, high-risk opportunities, emphasizing bold strategies and competitive advantages.
@ -42,17 +42,17 @@ Market Research Report:
-------------------------------------- --------------------------------------
Social Media Sentiment Report: Social Media Sentiment Report:
{sentiment_report} {sentiment_analysis}
-------------------------------------- --------------------------------------
Latest World Affairs Report: Latest World Affairs Report:
{news_report} {news_analysis}
-------------------------------------- --------------------------------------
Company Fundamentals Report: Company Fundamentals Report:
{fundamentals_report} {fundamentals_analysis}
-------------------------------------- --------------------------------------

View File

@ -17,12 +17,12 @@ def create_safe_debator(llm, config):
current_risky_response = risk_debate_state.get("current_risky_response", "") current_risky_response = risk_debate_state.get("current_risky_response", "")
current_neutral_response = risk_debate_state.get("current_neutral_response", "") current_neutral_response = risk_debate_state.get("current_neutral_response", "")
market_research_report = state["market_report"] market_research_report = state["market_analysis"]
sentiment_report = state["sentiment_report"] sentiment_analysis = state["sentiment_analysis"]
news_report = state["news_report"] news_analysis = state["news_analysis"]
fundamentals_report = state["fundamentals_report"] fundamentals_analysis = state["fundamentals_analysis"]
trader_decision = state["trader_investment_plan"] trader_decision = state["trader_team_plan"]
prompt = f""" prompt = f"""
As the Safe/Conservative Risk Analyst, your primary objective is to protect assets, minimize volatility, and ensure steady, reliable growth. As the Safe/Conservative Risk Analyst, your primary objective is to protect assets, minimize volatility, and ensure steady, reliable growth.
@ -41,17 +41,17 @@ Market Research Report:
-------------------------------------- --------------------------------------
Social Media Sentiment Report: Social Media Sentiment Report:
{sentiment_report} {sentiment_analysis}
-------------------------------------- --------------------------------------
Latest World Affairs Report: Latest World Affairs Report:
{news_report} {news_analysis}
-------------------------------------- --------------------------------------
Company Fundamentals Report: Company Fundamentals Report:
{fundamentals_report} {fundamentals_analysis}
-------------------------------------- --------------------------------------

View File

@ -16,12 +16,12 @@ def create_neutral_debator(llm, config):
current_risky_response = risk_debate_state.get("current_risky_response", "") current_risky_response = risk_debate_state.get("current_risky_response", "")
current_safe_response = risk_debate_state.get("current_safe_response", "") current_safe_response = risk_debate_state.get("current_safe_response", "")
market_research_report = state["market_report"] market_research_report = state["market_analysis"]
sentiment_report = state["sentiment_report"] sentiment_analysis = state["sentiment_analysis"]
news_report = state["news_report"] news_analysis = state["news_analysis"]
fundamentals_report = state["fundamentals_report"] fundamentals_analysis = state["fundamentals_analysis"]
trader_decision = state["trader_investment_plan"] trader_decision = state["trader_team_plan"]
prompt = f""" prompt = f"""
As the Neutral Risk Analyst, your role is to provide a balanced perspective, weighing both the potential benefits and risks of the trader's decision or plan. As the Neutral Risk Analyst, your role is to provide a balanced perspective, weighing both the potential benefits and risks of the trader's decision or plan.
@ -39,17 +39,17 @@ Market Research Report:
-------------------------------------- --------------------------------------
Social Media Sentiment Report: Social Media Sentiment Report:
{sentiment_report} {sentiment_analysis}
-------------------------------------- --------------------------------------
Latest World Affairs Report: Latest World Affairs Report:
{news_report} {news_analysis}
-------------------------------------- --------------------------------------
Company Fundamentals Report: Company Fundamentals Report:
{fundamentals_report} {fundamentals_analysis}
-------------------------------------- --------------------------------------

View File

@ -13,13 +13,13 @@ def create_trader(llm, memory, config):
def trader_node(state, name): def trader_node(state, name):
company_name = state["company_of_interest"] company_name = state["company_of_interest"]
investment_plan = state["investment_plan"] research_team_decision = state["research_team_decision"]
market_research_report = state["market_report"] market_research_report = state["market_analysis"]
sentiment_report = state["sentiment_report"] sentiment_analysis = state["sentiment_analysis"]
news_report = state["news_report"] news_analysis = state["news_analysis"]
fundamentals_report = state["fundamentals_report"] fundamentals_analysis = state["fundamentals_analysis"]
curr_situation = f"{market_research_report}\n\n{sentiment_report}\n\n{news_report}\n\n{fundamentals_report}" curr_situation = f"{market_research_report}\n\n{sentiment_analysis}\n\n{news_analysis}\n\n{fundamentals_analysis}"
past_memories = memory.get_memories(curr_situation, n_matches=2) past_memories = memory.get_memories(curr_situation, n_matches=2)
past_memory_str = "" past_memory_str = ""
@ -37,7 +37,7 @@ This plan incorporates insights from current technical market trends, macroecono
Use this plan as a foundation for evaluating your next trading decision. Use this plan as a foundation for evaluating your next trading decision.
Proposed Investment Plan: Proposed Investment Plan:
{investment_plan} {research_team_decision}
-------------------------------------- --------------------------------------
@ -69,7 +69,7 @@ Output language: ***{language_prompt}***
return { return {
"messages": [result], "messages": [result],
"trader_investment_plan": result.content, "trader_team_plan": result.content,
"sender": name, "sender": name,
} }

View File

@ -51,23 +51,23 @@ class AgentState(MessagesState):
sender: Annotated[str, "Agent that sent this message"] sender: Annotated[str, "Agent that sent this message"]
# research step # research step
market_report: Annotated[str, "Report from the Market Analyst"] market_analysis: Annotated[str, "Report from the Market Analyst"]
sentiment_report: Annotated[str, "Report from the Social Media Analyst"] sentiment_analysis: Annotated[str, "Report from the Social Media Analyst"]
news_report: Annotated[ news_analysis: Annotated[
str, "Report from the News Researcher of current world affairs" str, "Report from the News Researcher of current world affairs"
] ]
fundamentals_report: Annotated[str, "Report from the Fundamentals Researcher"] fundamentals_analysis: Annotated[str, "Report from the Fundamentals Researcher"]
# researcher team discussion step # researcher team discussion step
investment_debate_state: Annotated[ investment_debate_state: Annotated[
InvestDebateState, "Current state of the debate on if to invest or not" InvestDebateState, "Current state of the debate on if to invest or not"
] ]
investment_plan: Annotated[str, "Plan generated by the Analyst"] research_team_decision: Annotated[str, "Plan generated by the Analyst"]
trader_investment_plan: Annotated[str, "Plan generated by the Trader"] trader_team_plan: Annotated[str, "Plan generated by the Trader"]
# risk management team discussion step # risk management team discussion step
risk_debate_state: Annotated[ risk_debate_state: Annotated[
RiskDebateState, "Current state of the debate on evaluating risk" RiskDebateState, "Current state of the debate on evaluating risk"
] ]
final_trade_decision: Annotated[str, "Final decision made by the Risk Analysts"] final_portfolio_management_decision: Annotated[str, "Final decision made by the Risk Analysts"]

View File

@ -1,8 +1,8 @@
# TradingAgents/graph/propagation.py # TradingAgents/graph/propagation.py
from typing import Dict, Any from typing import Dict, Any
from tradingagents.agents.utils.agent_states import ( from tradingagents.agents.utils.agent_states import (
AgentState,
InvestDebateState, InvestDebateState,
RiskDebateState, RiskDebateState,
) )
@ -16,7 +16,7 @@ class Propagator:
self.max_recur_limit = max_recur_limit self.max_recur_limit = max_recur_limit
def create_initial_state( def create_initial_state(
self, company_name: str, trade_date: str self, company_name: str, trade_date: str
) -> Dict[str, Any]: ) -> Dict[str, Any]:
"""Create the initial state for the agent graph.""" """Create the initial state for the agent graph."""
return { return {
@ -35,10 +35,10 @@ class Propagator:
"count": 0, "count": 0,
} }
), ),
"market_report": "", "market_analysis": "",
"fundamentals_report": "", "fundamentals_analysis": "",
"sentiment_report": "", "sentiment_analysis": "",
"news_report": "", "news_analysis": "",
} }
def get_graph_args(self) -> Dict[str, Any]: def get_graph_args(self) -> Dict[str, Any]:

View File

@ -59,10 +59,10 @@ Output language: ***{self.language_prompt}***
def _extract_current_situation(self, current_state: Dict[str, Any]) -> str: def _extract_current_situation(self, current_state: Dict[str, Any]) -> str:
"""Extract the current market situation from the state.""" """Extract the current market situation from the state."""
curr_market_report = current_state["market_report"] curr_market_report = current_state["market_analysis"]
curr_sentiment_report = current_state["sentiment_report"] curr_sentiment_report = current_state["sentiment_analysis"]
curr_news_report = current_state["news_report"] curr_news_report = current_state["news_analysis"]
curr_fundamentals_report = current_state["fundamentals_report"] curr_fundamentals_report = current_state["fundamentals_analysis"]
return f"{curr_market_report}\n\n{curr_sentiment_report}\n\n{curr_news_report}\n\n{curr_fundamentals_report}" return f"{curr_market_report}\n\n{curr_sentiment_report}\n\n{curr_news_report}\n\n{curr_fundamentals_report}"
@ -112,7 +112,7 @@ Objective Market Reports for Reference: {situation}
def reflect_trader(self, current_state, returns_losses, trader_memory): def reflect_trader(self, current_state, returns_losses, trader_memory):
"""Reflect on trader's decision and update memory.""" """Reflect on trader's decision and update memory."""
situation = self._extract_current_situation(current_state) situation = self._extract_current_situation(current_state)
trader_decision = current_state["trader_investment_plan"] trader_decision = current_state["trader_team_plan"]
result = self._reflect_on_component( result = self._reflect_on_component(
"TRADER", trader_decision, situation, returns_losses "TRADER", trader_decision, situation, returns_losses

View File

@ -190,17 +190,17 @@ class TradingAgentsGraph:
self._log_state(trade_date, final_state) self._log_state(trade_date, final_state)
# Return decision and processed signal # Return decision and processed signal
return final_state, self.process_signal(final_state["final_trade_decision"]) return final_state, self.process_signal(final_state["final_portfolio_management_decision"])
def _log_state(self, trade_date, final_state): def _log_state(self, trade_date, final_state):
"""Log the final state to a JSON file.""" """Log the final state to a JSON file."""
self.log_states_dict[str(trade_date)] = { self.log_states_dict[str(trade_date)] = {
"company_of_interest": final_state["company_of_interest"], "company_of_interest": final_state["company_of_interest"],
"trade_date": final_state["trade_date"], "trade_date": final_state["trade_date"],
"market_report": final_state["market_report"], "market_analysis": final_state["market_analysis"],
"sentiment_report": final_state["sentiment_report"], "sentiment_analysis": final_state["sentiment_analysis"],
"news_report": final_state["news_report"], "news_analysis": final_state["news_analysis"],
"fundamentals_report": final_state["fundamentals_report"], "fundamentals_analysis": final_state["fundamentals_analysis"],
"investment_debate_state": { "investment_debate_state": {
"bull_history": final_state["investment_debate_state"]["bull_history"], "bull_history": final_state["investment_debate_state"]["bull_history"],
"bear_history": final_state["investment_debate_state"]["bear_history"], "bear_history": final_state["investment_debate_state"]["bear_history"],
@ -212,7 +212,7 @@ class TradingAgentsGraph:
"judge_decision" "judge_decision"
], ],
}, },
"trader_investment_decision": final_state["trader_investment_plan"], "trader_investment_decision": final_state["trader_team_plan"],
"risk_debate_state": { "risk_debate_state": {
"risky_history": final_state["risk_debate_state"]["risky_history"], "risky_history": final_state["risk_debate_state"]["risky_history"],
"safe_history": final_state["risk_debate_state"]["safe_history"], "safe_history": final_state["risk_debate_state"]["safe_history"],
@ -220,8 +220,8 @@ class TradingAgentsGraph:
"history": final_state["risk_debate_state"]["history"], "history": final_state["risk_debate_state"]["history"],
"judge_decision": final_state["risk_debate_state"]["judge_decision"], "judge_decision": final_state["risk_debate_state"]["judge_decision"],
}, },
"investment_plan": final_state["investment_plan"], "research_team_decision": final_state["research_team_decision"],
"final_trade_decision": final_state["final_trade_decision"], "final_portfolio_management_decision": final_state["final_portfolio_management_decision"],
} }
# Save to file # Save to file