rename reports
This commit is contained in:
parent
477a2570c6
commit
e6a18061a1
183
cli/main.py
183
cli/main.py
|
|
@ -1,16 +1,15 @@
|
|||
from typing import Optional
|
||||
import datetime
|
||||
import typer
|
||||
from pathlib import Path
|
||||
from functools import wraps
|
||||
from rich.console import Console
|
||||
from pathlib import Path
|
||||
|
||||
import typer
|
||||
from dotenv import load_dotenv
|
||||
from rich.console import Console
|
||||
|
||||
# Load environment variables from .env file
|
||||
load_dotenv()
|
||||
from rich.panel import Panel
|
||||
from rich.spinner import Spinner
|
||||
from rich.live import Live
|
||||
from rich.columns import Columns
|
||||
from rich.markdown import Markdown
|
||||
from rich.layout import Layout
|
||||
|
|
@ -18,15 +17,11 @@ from rich.text import Text
|
|||
from rich.live import Live
|
||||
from rich.table import Table
|
||||
from collections import deque
|
||||
import time
|
||||
from rich.tree import Tree
|
||||
from rich import box
|
||||
from rich.align import Align
|
||||
from rich.rule import Rule
|
||||
|
||||
from tradingagents.graph.trading_graph import TradingAgentsGraph
|
||||
from tradingagents.default_config import DEFAULT_CONFIG
|
||||
from cli.models import AnalystType
|
||||
from cli.utils import *
|
||||
|
||||
console = Console()
|
||||
|
|
@ -66,13 +61,13 @@ class MessageBuffer:
|
|||
}
|
||||
self.current_agent = None
|
||||
self.report_sections = {
|
||||
"market_report": None,
|
||||
"sentiment_report": None,
|
||||
"news_report": None,
|
||||
"fundamentals_report": None,
|
||||
"investment_plan": None,
|
||||
"trader_investment_plan": None,
|
||||
"final_trade_decision": None,
|
||||
"market_analysis": None,
|
||||
"sentiment_analysis": None,
|
||||
"news_analysis": None,
|
||||
"fundamentals_analysis": None,
|
||||
"research_team_decision": None,
|
||||
"trader_team_plan": None,
|
||||
"final_portfolio_management_decision": None,
|
||||
}
|
||||
|
||||
def add_message(self, message_type, content):
|
||||
|
|
@ -103,17 +98,17 @@ class MessageBuffer:
|
|||
if content is not None:
|
||||
latest_section = section
|
||||
latest_content = content
|
||||
|
||||
|
||||
if latest_section and latest_content:
|
||||
# Format the current section for display
|
||||
section_titles = {
|
||||
"market_report": "Market Analysis",
|
||||
"sentiment_report": "Social Sentiment",
|
||||
"news_report": "News Analysis",
|
||||
"fundamentals_report": "Fundamentals Analysis",
|
||||
"investment_plan": "Research Team Decision",
|
||||
"trader_investment_plan": "Trading Team Plan",
|
||||
"final_trade_decision": "Portfolio Management Decision",
|
||||
"market_analysis": "Market Analysis",
|
||||
"sentiment_analysis": "Social Sentiment",
|
||||
"news_analysis": "News Analysis",
|
||||
"fundamentals_analysis": "Fundamentals Analysis",
|
||||
"research_team_decision": "Research Team Decision",
|
||||
"trader_team_plan": "Trading Team Plan",
|
||||
"final_portfolio_management_decision": "Portfolio Management Decision",
|
||||
}
|
||||
self.current_report = (
|
||||
f"### {section_titles[latest_section]}\n{latest_content}"
|
||||
|
|
@ -127,46 +122,46 @@ class MessageBuffer:
|
|||
|
||||
# Analyst Team Reports
|
||||
if any(
|
||||
self.report_sections[section]
|
||||
for section in [
|
||||
"market_report",
|
||||
"sentiment_report",
|
||||
"news_report",
|
||||
"fundamentals_report",
|
||||
]
|
||||
self.report_sections[section]
|
||||
for section in [
|
||||
"market_analysis",
|
||||
"sentiment_analysis",
|
||||
"news_analysis",
|
||||
"fundamentals_analysis",
|
||||
]
|
||||
):
|
||||
report_parts.append("## Analyst Team Reports")
|
||||
if self.report_sections["market_report"]:
|
||||
if self.report_sections["market_analysis"]:
|
||||
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(
|
||||
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(
|
||||
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(
|
||||
f"### Fundamentals Analysis\n{self.report_sections['fundamentals_report']}"
|
||||
f"### Fundamentals Analysis\n{self.report_sections['fundamentals_analysis']}"
|
||||
)
|
||||
|
||||
# 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(f"{self.report_sections['investment_plan']}")
|
||||
report_parts.append(f"{self.report_sections['research_team_decision']}")
|
||||
|
||||
# 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(f"{self.report_sections['trader_investment_plan']}")
|
||||
report_parts.append(f"{self.report_sections['trader_team_plan']}")
|
||||
|
||||
# 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(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
|
||||
|
||||
|
|
@ -317,7 +312,7 @@ def update_display(layout, spinner_text=None):
|
|||
content_str = ' '.join(text_parts)
|
||||
elif not isinstance(content_str, str):
|
||||
content_str = str(content)
|
||||
|
||||
|
||||
# Truncate message content if too long
|
||||
if len(content_str) > 200:
|
||||
content_str = content_str[:197] + "..."
|
||||
|
|
@ -482,7 +477,7 @@ def get_user_selections():
|
|||
)
|
||||
)
|
||||
selected_llm_provider, backend_url = select_llm_provider()
|
||||
|
||||
|
||||
# Step 6: Thinking agents
|
||||
console.print(
|
||||
create_question_box(
|
||||
|
|
@ -537,10 +532,10 @@ def display_complete_report(final_state):
|
|||
analyst_reports = []
|
||||
|
||||
# Market Analyst Report
|
||||
if final_state.get("market_report"):
|
||||
if final_state.get("market_analysis"):
|
||||
analyst_reports.append(
|
||||
Panel(
|
||||
Markdown(final_state["market_report"]),
|
||||
Markdown(final_state["market_analysis"]),
|
||||
title="Market Analyst",
|
||||
border_style="blue",
|
||||
padding=(1, 2),
|
||||
|
|
@ -548,10 +543,10 @@ def display_complete_report(final_state):
|
|||
)
|
||||
|
||||
# Social Analyst Report
|
||||
if final_state.get("sentiment_report"):
|
||||
if final_state.get("sentiment_analysis"):
|
||||
analyst_reports.append(
|
||||
Panel(
|
||||
Markdown(final_state["sentiment_report"]),
|
||||
Markdown(final_state["sentiment_analysis"]),
|
||||
title="Social Analyst",
|
||||
border_style="blue",
|
||||
padding=(1, 2),
|
||||
|
|
@ -559,10 +554,10 @@ def display_complete_report(final_state):
|
|||
)
|
||||
|
||||
# News Analyst Report
|
||||
if final_state.get("news_report"):
|
||||
if final_state.get("news_analysis"):
|
||||
analyst_reports.append(
|
||||
Panel(
|
||||
Markdown(final_state["news_report"]),
|
||||
Markdown(final_state["news_analysis"]),
|
||||
title="News Analyst",
|
||||
border_style="blue",
|
||||
padding=(1, 2),
|
||||
|
|
@ -570,10 +565,10 @@ def display_complete_report(final_state):
|
|||
)
|
||||
|
||||
# Fundamentals Analyst Report
|
||||
if final_state.get("fundamentals_report"):
|
||||
if final_state.get("fundamentals_analysis"):
|
||||
analyst_reports.append(
|
||||
Panel(
|
||||
Markdown(final_state["fundamentals_report"]),
|
||||
Markdown(final_state["fundamentals_analysis"]),
|
||||
title="Fundamentals Analyst",
|
||||
border_style="blue",
|
||||
padding=(1, 2),
|
||||
|
|
@ -639,11 +634,11 @@ def display_complete_report(final_state):
|
|||
)
|
||||
|
||||
# III. Trading Team Reports
|
||||
if final_state.get("trader_investment_plan"):
|
||||
if final_state.get("trader_team_plan"):
|
||||
console.print(
|
||||
Panel(
|
||||
Panel(
|
||||
Markdown(final_state["trader_investment_plan"]),
|
||||
Markdown(final_state["trader_team_plan"]),
|
||||
title="Trader",
|
||||
border_style="blue",
|
||||
padding=(1, 2),
|
||||
|
|
@ -725,6 +720,7 @@ def update_research_team_status(status):
|
|||
for agent in research_team:
|
||||
message_buffer.update_agent_status(agent, status)
|
||||
|
||||
|
||||
def extract_content_string(content):
|
||||
"""Extract string content from various message formats."""
|
||||
if isinstance(content, str):
|
||||
|
|
@ -744,6 +740,7 @@ def extract_content_string(content):
|
|||
else:
|
||||
return str(content)
|
||||
|
||||
|
||||
def run_analysis():
|
||||
# First get all user selections
|
||||
selections = get_user_selections()
|
||||
|
|
@ -773,6 +770,7 @@ def run_analysis():
|
|||
|
||||
def save_message_decorator(obj, func_name):
|
||||
func = getattr(obj, func_name)
|
||||
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
func(*args, **kwargs)
|
||||
|
|
@ -780,10 +778,12 @@ def run_analysis():
|
|||
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)
|
||||
|
|
@ -791,10 +791,12 @@ def run_analysis():
|
|||
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)
|
||||
|
|
@ -804,6 +806,7 @@ def run_analysis():
|
|||
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")
|
||||
|
|
@ -871,7 +874,7 @@ def run_analysis():
|
|||
msg_type = "System"
|
||||
|
||||
# Add message to buffer
|
||||
message_buffer.add_message(msg_type, content)
|
||||
message_buffer.add_message(msg_type, content)
|
||||
|
||||
# If it's a tool call, add it to tool calls
|
||||
if hasattr(last_message, "tool_calls"):
|
||||
|
|
@ -886,9 +889,9 @@ def run_analysis():
|
|||
|
||||
# Update reports and agent status based on chunk content
|
||||
# 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(
|
||||
"market_report", chunk["market_report"]
|
||||
"market_analysis", chunk["market_analysis"]
|
||||
)
|
||||
message_buffer.update_agent_status("Market Analyst", "completed")
|
||||
# Set next analyst to in_progress
|
||||
|
|
@ -897,9 +900,9 @@ def run_analysis():
|
|||
"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(
|
||||
"sentiment_report", chunk["sentiment_report"]
|
||||
"sentiment_analysis", chunk["sentiment_analysis"]
|
||||
)
|
||||
message_buffer.update_agent_status("Social Analyst", "completed")
|
||||
# Set next analyst to in_progress
|
||||
|
|
@ -908,9 +911,9 @@ def run_analysis():
|
|||
"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(
|
||||
"news_report", chunk["news_report"]
|
||||
"news_analysis", chunk["news_analysis"]
|
||||
)
|
||||
message_buffer.update_agent_status("News Analyst", "completed")
|
||||
# Set next analyst to in_progress
|
||||
|
|
@ -919,9 +922,9 @@ def run_analysis():
|
|||
"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(
|
||||
"fundamentals_report", chunk["fundamentals_report"]
|
||||
"fundamentals_analysis", chunk["fundamentals_analysis"]
|
||||
)
|
||||
message_buffer.update_agent_status(
|
||||
"Fundamentals Analyst", "completed"
|
||||
|
|
@ -931,8 +934,8 @@ def run_analysis():
|
|||
|
||||
# Research Team - Handle Investment Debate State
|
||||
if (
|
||||
"investment_debate_state" in chunk
|
||||
and chunk["investment_debate_state"]
|
||||
"investment_debate_state" in chunk
|
||||
and chunk["investment_debate_state"]
|
||||
):
|
||||
debate_state = chunk["investment_debate_state"]
|
||||
|
||||
|
|
@ -947,7 +950,7 @@ def run_analysis():
|
|||
message_buffer.add_message("Reasoning", latest_bull)
|
||||
# Update research report with bull's latest analysis
|
||||
message_buffer.update_report_section(
|
||||
"investment_plan",
|
||||
"research_team_decision",
|
||||
f"### Bull Researcher Analysis\n{latest_bull}",
|
||||
)
|
||||
|
||||
|
|
@ -962,14 +965,14 @@ def run_analysis():
|
|||
message_buffer.add_message("Reasoning", latest_bear)
|
||||
# Update research report with bear's latest analysis
|
||||
message_buffer.update_report_section(
|
||||
"investment_plan",
|
||||
f"{message_buffer.report_sections['investment_plan']}\n\n### Bear Researcher Analysis\n{latest_bear}",
|
||||
"research_team_decision",
|
||||
f"{message_buffer.report_sections['research_team_decision']}\n\n### Bear Researcher Analysis\n{latest_bear}",
|
||||
)
|
||||
|
||||
# Update Research Manager status and final decision
|
||||
if (
|
||||
"judge_decision" in debate_state
|
||||
and debate_state["judge_decision"]
|
||||
"judge_decision" in debate_state
|
||||
and debate_state["judge_decision"]
|
||||
):
|
||||
# Keep all research team members in progress until final decision
|
||||
update_research_team_status("in_progress")
|
||||
|
|
@ -979,8 +982,8 @@ def run_analysis():
|
|||
)
|
||||
# Update research report with final decision
|
||||
message_buffer.update_report_section(
|
||||
"investment_plan",
|
||||
f"{message_buffer.report_sections['investment_plan']}\n\n### Research Manager Decision\n{debate_state['judge_decision']}",
|
||||
"research_team_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
|
||||
update_research_team_status("completed")
|
||||
|
|
@ -991,11 +994,11 @@ def run_analysis():
|
|||
|
||||
# Trading Team
|
||||
if (
|
||||
"trader_investment_plan" in chunk
|
||||
and chunk["trader_investment_plan"]
|
||||
"trader_team_plan" in chunk
|
||||
and chunk["trader_team_plan"]
|
||||
):
|
||||
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
|
||||
message_buffer.update_agent_status("Risky Analyst", "in_progress")
|
||||
|
|
@ -1006,8 +1009,8 @@ def run_analysis():
|
|||
|
||||
# Update Risky Analyst status and report
|
||||
if (
|
||||
"current_risky_response" in risk_state
|
||||
and risk_state["current_risky_response"]
|
||||
"current_risky_response" in risk_state
|
||||
and risk_state["current_risky_response"]
|
||||
):
|
||||
message_buffer.update_agent_status(
|
||||
"Risky Analyst", "in_progress"
|
||||
|
|
@ -1018,14 +1021,14 @@ def run_analysis():
|
|||
)
|
||||
# Update risk report with risky analyst's latest analysis only
|
||||
message_buffer.update_report_section(
|
||||
"final_trade_decision",
|
||||
"final_portfolio_management_decision",
|
||||
f"### Risky Analyst Analysis\n{risk_state['current_risky_response']}",
|
||||
)
|
||||
|
||||
# Update Safe Analyst status and report
|
||||
if (
|
||||
"current_safe_response" in risk_state
|
||||
and risk_state["current_safe_response"]
|
||||
"current_safe_response" in risk_state
|
||||
and risk_state["current_safe_response"]
|
||||
):
|
||||
message_buffer.update_agent_status(
|
||||
"Safe Analyst", "in_progress"
|
||||
|
|
@ -1036,14 +1039,14 @@ def run_analysis():
|
|||
)
|
||||
# Update risk report with safe analyst's latest analysis only
|
||||
message_buffer.update_report_section(
|
||||
"final_trade_decision",
|
||||
"final_portfolio_management_decision",
|
||||
f"### Safe Analyst Analysis\n{risk_state['current_safe_response']}",
|
||||
)
|
||||
|
||||
# Update Neutral Analyst status and report
|
||||
if (
|
||||
"current_neutral_response" in risk_state
|
||||
and risk_state["current_neutral_response"]
|
||||
"current_neutral_response" in risk_state
|
||||
and risk_state["current_neutral_response"]
|
||||
):
|
||||
message_buffer.update_agent_status(
|
||||
"Neutral Analyst", "in_progress"
|
||||
|
|
@ -1054,7 +1057,7 @@ def run_analysis():
|
|||
)
|
||||
# Update risk report with neutral analyst's latest analysis only
|
||||
message_buffer.update_report_section(
|
||||
"final_trade_decision",
|
||||
"final_portfolio_management_decision",
|
||||
f"### Neutral Analyst Analysis\n{risk_state['current_neutral_response']}",
|
||||
)
|
||||
|
||||
|
|
@ -1069,7 +1072,7 @@ def run_analysis():
|
|||
)
|
||||
# Update risk report with final decision only
|
||||
message_buffer.update_report_section(
|
||||
"final_trade_decision",
|
||||
"final_portfolio_management_decision",
|
||||
f"### Portfolio Manager Decision\n{risk_state['judge_decision']}",
|
||||
)
|
||||
# Mark risk analysts as completed
|
||||
|
|
@ -1089,7 +1092,7 @@ def run_analysis():
|
|||
|
||||
# Get final state and decision
|
||||
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
|
||||
for agent in message_buffer.agent_status:
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ Output language: ***{language_prompt}***
|
|||
|
||||
return {
|
||||
"messages": [result],
|
||||
"fundamentals_report": report,
|
||||
"fundamentals_analysis": report,
|
||||
}
|
||||
|
||||
return fundamentals_analyst_node
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ Output language: ***{language_prompt}***
|
|||
|
||||
return {
|
||||
"messages": [result],
|
||||
"market_report": report,
|
||||
"market_analysis": report,
|
||||
}
|
||||
|
||||
return market_analyst_node
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ Output language: ***{language_prompt}***
|
|||
|
||||
return {
|
||||
"messages": [result],
|
||||
"news_report": report,
|
||||
"news_analysis": report,
|
||||
}
|
||||
|
||||
return news_analyst_node
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ Output language: ***{language_prompt}***
|
|||
|
||||
return {
|
||||
"messages": [result],
|
||||
"sentiment_report": report,
|
||||
"sentiment_analysis": report,
|
||||
}
|
||||
|
||||
return social_media_analyst_node
|
||||
|
|
|
|||
|
|
@ -10,14 +10,14 @@ def create_research_manager(llm, memory, config):
|
|||
|
||||
def research_manager_node(state) -> dict:
|
||||
history = state["investment_debate_state"].get("history", "")
|
||||
market_research_report = state["market_report"]
|
||||
sentiment_report = state["sentiment_report"]
|
||||
news_report = state["news_report"]
|
||||
fundamentals_report = state["fundamentals_report"]
|
||||
market_research_report = state["market_analysis"]
|
||||
sentiment_analysis = state["sentiment_analysis"]
|
||||
news_analysis = state["news_analysis"]
|
||||
fundamentals_analysis = state["fundamentals_analysis"]
|
||||
|
||||
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_memory_str = ""
|
||||
|
|
@ -56,7 +56,7 @@ Output language: ***{language_prompt}***
|
|||
|
||||
return {
|
||||
"investment_debate_state": new_investment_debate_state,
|
||||
"investment_plan": response.content,
|
||||
"research_team_decision": response.content,
|
||||
}
|
||||
|
||||
return research_manager_node
|
||||
|
|
|
|||
|
|
@ -13,13 +13,13 @@ def create_risk_manager(llm, memory, config):
|
|||
|
||||
history = state["risk_debate_state"]["history"]
|
||||
risk_debate_state = state["risk_debate_state"]
|
||||
market_research_report = state["market_report"]
|
||||
news_report = state["news_report"]
|
||||
fundamentals_report = state["news_report"]
|
||||
sentiment_report = state["sentiment_report"]
|
||||
trader_plan = state["investment_plan"]
|
||||
market_research_report = state["market_analysis"]
|
||||
news_analysis = state["news_analysis"]
|
||||
fundamentals_analysis = state["news_analysis"]
|
||||
sentiment_analysis = state["sentiment_analysis"]
|
||||
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_memory_str = ""
|
||||
|
|
@ -68,7 +68,7 @@ Output language: ***{language_prompt}***
|
|||
|
||||
return {
|
||||
"risk_debate_state": new_risk_debate_state,
|
||||
"final_trade_decision": response.content,
|
||||
"final_portfolio_management_decision": response.content,
|
||||
}
|
||||
|
||||
return risk_manager_node
|
||||
|
|
|
|||
|
|
@ -14,12 +14,12 @@ def create_bear_researcher(llm, memory, config):
|
|||
bear_history = investment_debate_state.get("bear_history", "")
|
||||
|
||||
current_response = investment_debate_state.get("current_response", "")
|
||||
market_research_report = state["market_report"]
|
||||
sentiment_report = state["sentiment_report"]
|
||||
news_report = state["news_report"]
|
||||
fundamentals_report = state["fundamentals_report"]
|
||||
market_research_report = state["market_analysis"]
|
||||
sentiment_analysis = state["sentiment_analysis"]
|
||||
news_analysis = state["news_analysis"]
|
||||
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_memory_str = ""
|
||||
|
|
@ -46,17 +46,17 @@ Market research report:
|
|||
|
||||
--------------------------------------
|
||||
Social media sentiment report:
|
||||
{sentiment_report}
|
||||
{sentiment_analysis}
|
||||
|
||||
|
||||
--------------------------------------
|
||||
Latest world affairs news:
|
||||
{news_report}
|
||||
{news_analysis}
|
||||
|
||||
|
||||
--------------------------------------
|
||||
Company fundamentals report:
|
||||
{fundamentals_report}
|
||||
{fundamentals_analysis}
|
||||
|
||||
|
||||
--------------------------------------
|
||||
|
|
|
|||
|
|
@ -14,12 +14,12 @@ def create_bull_researcher(llm, memory, config):
|
|||
bull_history = investment_debate_state.get("bull_history", "")
|
||||
|
||||
current_response = investment_debate_state.get("current_response", "")
|
||||
market_research_report = state["market_report"]
|
||||
sentiment_report = state["sentiment_report"]
|
||||
news_report = state["news_report"]
|
||||
fundamentals_report = state["fundamentals_report"]
|
||||
market_research_report = state["market_analysis"]
|
||||
sentiment_analysis = state["sentiment_analysis"]
|
||||
news_analysis = state["news_analysis"]
|
||||
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_memory_str = ""
|
||||
|
|
@ -44,17 +44,17 @@ Market research report:
|
|||
|
||||
--------------------------------------
|
||||
Social media sentiment report:
|
||||
{sentiment_report}
|
||||
{sentiment_analysis}
|
||||
|
||||
|
||||
--------------------------------------
|
||||
Latest world affairs news:
|
||||
{news_report}
|
||||
{news_analysis}
|
||||
|
||||
|
||||
--------------------------------------
|
||||
Company fundamentals report:
|
||||
{fundamentals_report}
|
||||
{fundamentals_analysis}
|
||||
|
||||
|
||||
--------------------------------------
|
||||
|
|
|
|||
|
|
@ -16,12 +16,12 @@ def create_risky_debator(llm, config):
|
|||
current_safe_response = risk_debate_state.get("current_safe_response", "")
|
||||
current_neutral_response = risk_debate_state.get("current_neutral_response", "")
|
||||
|
||||
market_research_report = state["market_report"]
|
||||
sentiment_report = state["sentiment_report"]
|
||||
news_report = state["news_report"]
|
||||
fundamentals_report = state["fundamentals_report"]
|
||||
market_research_report = state["market_analysis"]
|
||||
sentiment_analysis = state["sentiment_analysis"]
|
||||
news_analysis = state["news_analysis"]
|
||||
fundamentals_analysis = state["fundamentals_analysis"]
|
||||
|
||||
trader_decision = state["trader_investment_plan"]
|
||||
trader_decision = state["trader_team_plan"]
|
||||
|
||||
prompt = f"""
|
||||
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:
|
||||
{sentiment_report}
|
||||
{sentiment_analysis}
|
||||
|
||||
|
||||
--------------------------------------
|
||||
Latest World Affairs Report:
|
||||
{news_report}
|
||||
{news_analysis}
|
||||
|
||||
|
||||
--------------------------------------
|
||||
Company Fundamentals Report:
|
||||
{fundamentals_report}
|
||||
{fundamentals_analysis}
|
||||
|
||||
|
||||
--------------------------------------
|
||||
|
|
|
|||
|
|
@ -17,12 +17,12 @@ def create_safe_debator(llm, config):
|
|||
current_risky_response = risk_debate_state.get("current_risky_response", "")
|
||||
current_neutral_response = risk_debate_state.get("current_neutral_response", "")
|
||||
|
||||
market_research_report = state["market_report"]
|
||||
sentiment_report = state["sentiment_report"]
|
||||
news_report = state["news_report"]
|
||||
fundamentals_report = state["fundamentals_report"]
|
||||
market_research_report = state["market_analysis"]
|
||||
sentiment_analysis = state["sentiment_analysis"]
|
||||
news_analysis = state["news_analysis"]
|
||||
fundamentals_analysis = state["fundamentals_analysis"]
|
||||
|
||||
trader_decision = state["trader_investment_plan"]
|
||||
trader_decision = state["trader_team_plan"]
|
||||
|
||||
prompt = f"""
|
||||
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:
|
||||
{sentiment_report}
|
||||
{sentiment_analysis}
|
||||
|
||||
|
||||
--------------------------------------
|
||||
Latest World Affairs Report:
|
||||
{news_report}
|
||||
{news_analysis}
|
||||
|
||||
|
||||
--------------------------------------
|
||||
Company Fundamentals Report:
|
||||
{fundamentals_report}
|
||||
{fundamentals_analysis}
|
||||
|
||||
|
||||
--------------------------------------
|
||||
|
|
|
|||
|
|
@ -16,12 +16,12 @@ def create_neutral_debator(llm, config):
|
|||
current_risky_response = risk_debate_state.get("current_risky_response", "")
|
||||
current_safe_response = risk_debate_state.get("current_safe_response", "")
|
||||
|
||||
market_research_report = state["market_report"]
|
||||
sentiment_report = state["sentiment_report"]
|
||||
news_report = state["news_report"]
|
||||
fundamentals_report = state["fundamentals_report"]
|
||||
market_research_report = state["market_analysis"]
|
||||
sentiment_analysis = state["sentiment_analysis"]
|
||||
news_analysis = state["news_analysis"]
|
||||
fundamentals_analysis = state["fundamentals_analysis"]
|
||||
|
||||
trader_decision = state["trader_investment_plan"]
|
||||
trader_decision = state["trader_team_plan"]
|
||||
|
||||
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.
|
||||
|
|
@ -39,17 +39,17 @@ Market Research Report:
|
|||
|
||||
--------------------------------------
|
||||
Social Media Sentiment Report:
|
||||
{sentiment_report}
|
||||
{sentiment_analysis}
|
||||
|
||||
|
||||
--------------------------------------
|
||||
Latest World Affairs Report:
|
||||
{news_report}
|
||||
{news_analysis}
|
||||
|
||||
|
||||
--------------------------------------
|
||||
Company Fundamentals Report:
|
||||
{fundamentals_report}
|
||||
{fundamentals_analysis}
|
||||
|
||||
|
||||
--------------------------------------
|
||||
|
|
|
|||
|
|
@ -13,13 +13,13 @@ def create_trader(llm, memory, config):
|
|||
|
||||
def trader_node(state, name):
|
||||
company_name = state["company_of_interest"]
|
||||
investment_plan = state["investment_plan"]
|
||||
market_research_report = state["market_report"]
|
||||
sentiment_report = state["sentiment_report"]
|
||||
news_report = state["news_report"]
|
||||
fundamentals_report = state["fundamentals_report"]
|
||||
research_team_decision = state["research_team_decision"]
|
||||
market_research_report = state["market_analysis"]
|
||||
sentiment_analysis = state["sentiment_analysis"]
|
||||
news_analysis = state["news_analysis"]
|
||||
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_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.
|
||||
|
||||
Proposed Investment Plan:
|
||||
{investment_plan}
|
||||
{research_team_decision}
|
||||
|
||||
|
||||
--------------------------------------
|
||||
|
|
@ -69,7 +69,7 @@ Output language: ***{language_prompt}***
|
|||
|
||||
return {
|
||||
"messages": [result],
|
||||
"trader_investment_plan": result.content,
|
||||
"trader_team_plan": result.content,
|
||||
"sender": name,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,23 +51,23 @@ class AgentState(MessagesState):
|
|||
sender: Annotated[str, "Agent that sent this message"]
|
||||
|
||||
# research step
|
||||
market_report: Annotated[str, "Report from the Market Analyst"]
|
||||
sentiment_report: Annotated[str, "Report from the Social Media Analyst"]
|
||||
news_report: Annotated[
|
||||
market_analysis: Annotated[str, "Report from the Market Analyst"]
|
||||
sentiment_analysis: Annotated[str, "Report from the Social Media Analyst"]
|
||||
news_analysis: Annotated[
|
||||
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
|
||||
investment_debate_state: Annotated[
|
||||
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_debate_state: Annotated[
|
||||
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"]
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
# TradingAgents/graph/propagation.py
|
||||
|
||||
from typing import Dict, Any
|
||||
|
||||
from tradingagents.agents.utils.agent_states import (
|
||||
AgentState,
|
||||
InvestDebateState,
|
||||
RiskDebateState,
|
||||
)
|
||||
|
|
@ -16,7 +16,7 @@ class Propagator:
|
|||
self.max_recur_limit = max_recur_limit
|
||||
|
||||
def create_initial_state(
|
||||
self, company_name: str, trade_date: str
|
||||
self, company_name: str, trade_date: str
|
||||
) -> Dict[str, Any]:
|
||||
"""Create the initial state for the agent graph."""
|
||||
return {
|
||||
|
|
@ -35,10 +35,10 @@ class Propagator:
|
|||
"count": 0,
|
||||
}
|
||||
),
|
||||
"market_report": "",
|
||||
"fundamentals_report": "",
|
||||
"sentiment_report": "",
|
||||
"news_report": "",
|
||||
"market_analysis": "",
|
||||
"fundamentals_analysis": "",
|
||||
"sentiment_analysis": "",
|
||||
"news_analysis": "",
|
||||
}
|
||||
|
||||
def get_graph_args(self) -> Dict[str, Any]:
|
||||
|
|
|
|||
|
|
@ -59,10 +59,10 @@ Output language: ***{self.language_prompt}***
|
|||
|
||||
def _extract_current_situation(self, current_state: Dict[str, Any]) -> str:
|
||||
"""Extract the current market situation from the state."""
|
||||
curr_market_report = current_state["market_report"]
|
||||
curr_sentiment_report = current_state["sentiment_report"]
|
||||
curr_news_report = current_state["news_report"]
|
||||
curr_fundamentals_report = current_state["fundamentals_report"]
|
||||
curr_market_report = current_state["market_analysis"]
|
||||
curr_sentiment_report = current_state["sentiment_analysis"]
|
||||
curr_news_report = current_state["news_analysis"]
|
||||
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}"
|
||||
|
||||
|
|
@ -112,7 +112,7 @@ Objective Market Reports for Reference: {situation}
|
|||
def reflect_trader(self, current_state, returns_losses, trader_memory):
|
||||
"""Reflect on trader's decision and update memory."""
|
||||
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(
|
||||
"TRADER", trader_decision, situation, returns_losses
|
||||
|
|
|
|||
|
|
@ -190,17 +190,17 @@ class TradingAgentsGraph:
|
|||
self._log_state(trade_date, final_state)
|
||||
|
||||
# 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):
|
||||
"""Log the final state to a JSON file."""
|
||||
self.log_states_dict[str(trade_date)] = {
|
||||
"company_of_interest": final_state["company_of_interest"],
|
||||
"trade_date": final_state["trade_date"],
|
||||
"market_report": final_state["market_report"],
|
||||
"sentiment_report": final_state["sentiment_report"],
|
||||
"news_report": final_state["news_report"],
|
||||
"fundamentals_report": final_state["fundamentals_report"],
|
||||
"market_analysis": final_state["market_analysis"],
|
||||
"sentiment_analysis": final_state["sentiment_analysis"],
|
||||
"news_analysis": final_state["news_analysis"],
|
||||
"fundamentals_analysis": final_state["fundamentals_analysis"],
|
||||
"investment_debate_state": {
|
||||
"bull_history": final_state["investment_debate_state"]["bull_history"],
|
||||
"bear_history": final_state["investment_debate_state"]["bear_history"],
|
||||
|
|
@ -212,7 +212,7 @@ class TradingAgentsGraph:
|
|||
"judge_decision"
|
||||
],
|
||||
},
|
||||
"trader_investment_decision": final_state["trader_investment_plan"],
|
||||
"trader_investment_decision": final_state["trader_team_plan"],
|
||||
"risk_debate_state": {
|
||||
"risky_history": final_state["risk_debate_state"]["risky_history"],
|
||||
"safe_history": final_state["risk_debate_state"]["safe_history"],
|
||||
|
|
@ -220,8 +220,8 @@ class TradingAgentsGraph:
|
|||
"history": final_state["risk_debate_state"]["history"],
|
||||
"judge_decision": final_state["risk_debate_state"]["judge_decision"],
|
||||
},
|
||||
"investment_plan": final_state["investment_plan"],
|
||||
"final_trade_decision": final_state["final_trade_decision"],
|
||||
"research_team_decision": final_state["research_team_decision"],
|
||||
"final_portfolio_management_decision": final_state["final_portfolio_management_decision"],
|
||||
}
|
||||
|
||||
# Save to file
|
||||
|
|
|
|||
Loading…
Reference in New Issue