mirror of
https://github.com/TauricResearch/TradingAgents.git
synced 2026-09-26 22:42:40 +03:00
chore: remove code nothing uses
- is_yahoo_safe, has_checkpoint, get_wall_times, the graph's curr_state and the project_dir config key - the CLI's final_report and current_agent state, its duplicate get_analysis_date and the save_report_to_disk wrapper - the dotenv import guard (a hard dependency) and a warning filter for langgraph-checkpoint 4.0.3
This commit is contained in:
+1
-55
@@ -112,9 +112,7 @@ class MessageBuffer:
|
|||||||
self.messages = deque(maxlen=max_length)
|
self.messages = deque(maxlen=max_length)
|
||||||
self.tool_calls = deque(maxlen=max_length)
|
self.tool_calls = deque(maxlen=max_length)
|
||||||
self.current_report = None
|
self.current_report = None
|
||||||
self.final_report = None # Store the complete final report
|
|
||||||
self.agent_status = {}
|
self.agent_status = {}
|
||||||
self.current_agent = None
|
|
||||||
self.report_sections = {}
|
self.report_sections = {}
|
||||||
self.selected_analysts = []
|
self.selected_analysts = []
|
||||||
self._processed_message_ids = set()
|
self._processed_message_ids = set()
|
||||||
@@ -148,8 +146,6 @@ class MessageBuffer:
|
|||||||
|
|
||||||
# Reset other state
|
# Reset other state
|
||||||
self.current_report = None
|
self.current_report = None
|
||||||
self.final_report = None
|
|
||||||
self.current_agent = None
|
|
||||||
self.messages.clear()
|
self.messages.clear()
|
||||||
self.tool_calls.clear()
|
self.tool_calls.clear()
|
||||||
self._processed_message_ids.clear()
|
self._processed_message_ids.clear()
|
||||||
@@ -186,7 +182,6 @@ class MessageBuffer:
|
|||||||
def update_agent_status(self, agent, status):
|
def update_agent_status(self, agent, status):
|
||||||
if agent in self.agent_status:
|
if agent in self.agent_status:
|
||||||
self.agent_status[agent] = status
|
self.agent_status[agent] = status
|
||||||
self.current_agent = agent
|
|
||||||
|
|
||||||
def update_report_section(self, section_name, content):
|
def update_report_section(self, section_name, content):
|
||||||
if section_name in self.report_sections:
|
if section_name in self.report_sections:
|
||||||
@@ -219,50 +214,6 @@ class MessageBuffer:
|
|||||||
f"### {section_titles[latest_section]}\n{latest_content}"
|
f"### {section_titles[latest_section]}\n{latest_content}"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Update the final complete report
|
|
||||||
self._update_final_report()
|
|
||||||
|
|
||||||
def _update_final_report(self):
|
|
||||||
report_parts = []
|
|
||||||
|
|
||||||
# Analyst Team Reports - use .get() to handle missing sections
|
|
||||||
analyst_sections = ["market_report", "sentiment_report", "news_report", "fundamentals_report"]
|
|
||||||
if any(self.report_sections.get(section) for section in analyst_sections):
|
|
||||||
report_parts.append("## Analyst Team Reports")
|
|
||||||
if self.report_sections.get("market_report"):
|
|
||||||
report_parts.append(
|
|
||||||
f"### Market Analysis\n{self.report_sections['market_report']}"
|
|
||||||
)
|
|
||||||
if self.report_sections.get("sentiment_report"):
|
|
||||||
report_parts.append(
|
|
||||||
f"### Social Sentiment\n{self.report_sections['sentiment_report']}"
|
|
||||||
)
|
|
||||||
if self.report_sections.get("news_report"):
|
|
||||||
report_parts.append(
|
|
||||||
f"### News Analysis\n{self.report_sections['news_report']}"
|
|
||||||
)
|
|
||||||
if self.report_sections.get("fundamentals_report"):
|
|
||||||
report_parts.append(
|
|
||||||
f"### Fundamentals Analysis\n{self.report_sections['fundamentals_report']}"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Research Team Reports
|
|
||||||
if self.report_sections.get("investment_plan"):
|
|
||||||
report_parts.append("## Research Team Decision")
|
|
||||||
report_parts.append(f"{self.report_sections['investment_plan']}")
|
|
||||||
|
|
||||||
# Trading Team Reports
|
|
||||||
if self.report_sections.get("trader_investment_plan"):
|
|
||||||
report_parts.append("## Trading Team Plan")
|
|
||||||
report_parts.append(f"{self.report_sections['trader_investment_plan']}")
|
|
||||||
|
|
||||||
# Portfolio Management Decision
|
|
||||||
if self.report_sections.get("final_trade_decision"):
|
|
||||||
report_parts.append("## Portfolio Management Decision")
|
|
||||||
report_parts.append(f"{self.report_sections['final_trade_decision']}")
|
|
||||||
|
|
||||||
self.final_report = "\n\n".join(report_parts) if report_parts else None
|
|
||||||
|
|
||||||
|
|
||||||
message_buffer = MessageBuffer()
|
message_buffer = MessageBuffer()
|
||||||
|
|
||||||
@@ -780,11 +731,6 @@ def get_analysis_date():
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def save_report_to_disk(final_state, ticker: str, save_path: Path):
|
|
||||||
"""Save the complete analysis report to disk (shared CLI/API writer)."""
|
|
||||||
return write_report_tree(final_state, ticker, save_path)
|
|
||||||
|
|
||||||
|
|
||||||
def display_complete_report(final_state):
|
def display_complete_report(final_state):
|
||||||
"""Display the complete analysis report sequentially (avoids truncation)."""
|
"""Display the complete analysis report sequentially (avoids truncation)."""
|
||||||
console.print()
|
console.print()
|
||||||
@@ -1344,7 +1290,7 @@ def run_analysis(checkpoint: bool | None = None, portfolio=None):
|
|||||||
).strip()
|
).strip()
|
||||||
save_path = Path(save_path_str)
|
save_path = Path(save_path_str)
|
||||||
try:
|
try:
|
||||||
report_file = save_report_to_disk(final_state, selections["ticker"], save_path)
|
report_file = write_report_tree(final_state, selections["ticker"], save_path)
|
||||||
console.print(f"\n[green]✓ Report saved to:[/green] {save_path.resolve()}")
|
console.print(f"\n[green]✓ Report saved to:[/green] {save_path.resolve()}")
|
||||||
console.print(f" [dim]Complete report:[/dim] {report_file.name}")
|
console.print(f" [dim]Complete report:[/dim] {report_file.name}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -99,39 +99,6 @@ def filter_analysts_for_asset_type(
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def get_analysis_date() -> str:
|
|
||||||
"""Prompt the user to enter a date in YYYY-MM-DD format."""
|
|
||||||
import re
|
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
def validate_date(date_str: str) -> bool:
|
|
||||||
if not re.match(r"^\d{4}-\d{2}-\d{2}$", date_str):
|
|
||||||
return False
|
|
||||||
try:
|
|
||||||
datetime.strptime(date_str, "%Y-%m-%d")
|
|
||||||
return True
|
|
||||||
except ValueError:
|
|
||||||
return False
|
|
||||||
|
|
||||||
date = questionary.text(
|
|
||||||
"Enter the analysis date (YYYY-MM-DD):",
|
|
||||||
validate=lambda x: validate_date(x.strip())
|
|
||||||
or "Please enter a valid date in YYYY-MM-DD format.",
|
|
||||||
style=questionary.Style(
|
|
||||||
[
|
|
||||||
("text", "fg:green"),
|
|
||||||
("highlighted", "noinherit"),
|
|
||||||
]
|
|
||||||
),
|
|
||||||
).ask()
|
|
||||||
|
|
||||||
if not date:
|
|
||||||
console.print("\n[red]No date provided. Exiting...[/red]")
|
|
||||||
exit(1)
|
|
||||||
|
|
||||||
return date.strip()
|
|
||||||
|
|
||||||
|
|
||||||
def _matching_choice(options, default):
|
def _matching_choice(options, default):
|
||||||
"""The option value equal to ``default``, or None to leave the menu as is."""
|
"""The option value equal to ``default``, or None to leave the menu as is."""
|
||||||
return next((value for _, value in options if value == default), None)
|
return next((value for _, value in options if value == default), None)
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ class AnalystWallTimeTrackerTests(unittest.TestCase):
|
|||||||
tracker.mark_started("market", started_at=10.0)
|
tracker.mark_started("market", started_at=10.0)
|
||||||
tracker.mark_completed("market", completed_at=13.5)
|
tracker.mark_completed("market", completed_at=13.5)
|
||||||
|
|
||||||
self.assertEqual(tracker.get_wall_times(), {"market": 3.5})
|
self.assertEqual(tracker.format_summary(), "Analyst wall time: Market 3.50s")
|
||||||
|
|
||||||
def test_formats_summary_in_plan_order(self):
|
def test_formats_summary_in_plan_order(self):
|
||||||
plan = build_analyst_execution_plan(["news", "market"])
|
plan = build_analyst_execution_plan(["news", "market"])
|
||||||
@@ -70,21 +70,18 @@ class AnalystWallTimeTrackerTests(unittest.TestCase):
|
|||||||
tracker = AnalystWallTimeTracker(plan)
|
tracker = AnalystWallTimeTracker(plan)
|
||||||
|
|
||||||
sync_analyst_tracker_from_chunk(tracker, {}, now=10.0)
|
sync_analyst_tracker_from_chunk(tracker, {}, now=10.0)
|
||||||
self.assertEqual(tracker.get_wall_times(), {})
|
self.assertEqual(tracker.format_summary(), "Analyst wall time: pending")
|
||||||
|
|
||||||
sync_analyst_tracker_from_chunk(
|
sync_analyst_tracker_from_chunk(
|
||||||
tracker,
|
tracker,
|
||||||
{"market_report": "done"},
|
{"market_report": "done"},
|
||||||
now=13.0,
|
now=13.0,
|
||||||
)
|
)
|
||||||
self.assertEqual(tracker.get_wall_times(), {"market": 3.0})
|
self.assertEqual(tracker.format_summary(), "Analyst wall time: Market 3.00s")
|
||||||
|
|
||||||
sync_analyst_tracker_from_chunk(
|
sync_analyst_tracker_from_chunk(
|
||||||
tracker,
|
tracker,
|
||||||
{"market_report": "done", "news_report": "done"},
|
{"market_report": "done", "news_report": "done"},
|
||||||
now=18.0,
|
now=18.0,
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(tracker.format_summary(), "Analyst wall time: Market 3.00s | News 5.00s")
|
||||||
tracker.get_wall_times(),
|
|
||||||
{"market": 3.0, "news": 5.0},
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ from tradingagents.graph.checkpointer import (
|
|||||||
checkpoint_step,
|
checkpoint_step,
|
||||||
clear_checkpoint,
|
clear_checkpoint,
|
||||||
get_checkpointer,
|
get_checkpointer,
|
||||||
has_checkpoint,
|
|
||||||
thread_id,
|
thread_id,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -63,7 +62,7 @@ class TestCheckpointResume(unittest.TestCase):
|
|||||||
graph.invoke({"count": 0}, config=cfg)
|
graph.invoke({"count": 0}, config=cfg)
|
||||||
|
|
||||||
# Checkpoint should exist at step 1 (analyst completed)
|
# Checkpoint should exist at step 1 (analyst completed)
|
||||||
self.assertTrue(has_checkpoint(self.tmpdir, self.ticker, self.date))
|
self.assertIsNotNone(checkpoint_step(self.tmpdir, self.ticker, self.date))
|
||||||
step = checkpoint_step(self.tmpdir, self.ticker, self.date)
|
step = checkpoint_step(self.tmpdir, self.ticker, self.date)
|
||||||
self.assertEqual(step, 1)
|
self.assertEqual(step, 1)
|
||||||
|
|
||||||
@@ -90,11 +89,11 @@ class TestCheckpointResume(unittest.TestCase):
|
|||||||
with self.assertRaises(RuntimeError):
|
with self.assertRaises(RuntimeError):
|
||||||
graph.invoke({"count": 0}, config=cfg)
|
graph.invoke({"count": 0}, config=cfg)
|
||||||
|
|
||||||
self.assertTrue(has_checkpoint(self.tmpdir, self.ticker, self.date))
|
self.assertIsNotNone(checkpoint_step(self.tmpdir, self.ticker, self.date))
|
||||||
|
|
||||||
# Clear it
|
# Clear it
|
||||||
clear_checkpoint(self.tmpdir, self.ticker, self.date)
|
clear_checkpoint(self.tmpdir, self.ticker, self.date)
|
||||||
self.assertFalse(has_checkpoint(self.tmpdir, self.ticker, self.date))
|
self.assertIsNone(checkpoint_step(self.tmpdir, self.ticker, self.date))
|
||||||
|
|
||||||
# Fresh run succeeds from scratch
|
# Fresh run succeeds from scratch
|
||||||
_should_crash = False
|
_should_crash = False
|
||||||
@@ -119,10 +118,10 @@ class TestCheckpointResume(unittest.TestCase):
|
|||||||
with self.assertRaises(RuntimeError):
|
with self.assertRaises(RuntimeError):
|
||||||
graph.invoke({"count": 0}, config={"configurable": {"thread_id": tid1}})
|
graph.invoke({"count": 0}, config={"configurable": {"thread_id": tid1}})
|
||||||
|
|
||||||
self.assertTrue(has_checkpoint(self.tmpdir, self.ticker, self.date))
|
self.assertIsNotNone(checkpoint_step(self.tmpdir, self.ticker, self.date))
|
||||||
|
|
||||||
# date2 should have no checkpoint
|
# date2 should have no checkpoint
|
||||||
self.assertFalse(has_checkpoint(self.tmpdir, self.ticker, date2))
|
self.assertIsNone(checkpoint_step(self.tmpdir, self.ticker, date2))
|
||||||
|
|
||||||
# Run with date2 — should start fresh and succeed
|
# Run with date2 — should start fresh and succeed
|
||||||
_should_crash = False
|
_should_crash = False
|
||||||
@@ -137,7 +136,7 @@ class TestCheckpointResume(unittest.TestCase):
|
|||||||
self.assertEqual(result["count"], 11)
|
self.assertEqual(result["count"], 11)
|
||||||
|
|
||||||
# Original date checkpoint still exists (untouched)
|
# Original date checkpoint still exists (untouched)
|
||||||
self.assertTrue(has_checkpoint(self.tmpdir, self.ticker, self.date))
|
self.assertIsNotNone(checkpoint_step(self.tmpdir, self.ticker, self.date))
|
||||||
|
|
||||||
|
|
||||||
class TestCheckpointSignature(unittest.TestCase):
|
class TestCheckpointSignature(unittest.TestCase):
|
||||||
@@ -178,9 +177,9 @@ class TestCheckpointSignature(unittest.TestCase):
|
|||||||
with self.assertRaises(RuntimeError):
|
with self.assertRaises(RuntimeError):
|
||||||
graph.invoke({"count": 0}, config={"configurable": {"thread_id": tid1}})
|
graph.invoke({"count": 0}, config={"configurable": {"thread_id": tid1}})
|
||||||
|
|
||||||
self.assertTrue(has_checkpoint(self.tmpdir, self.ticker, self.date, sig1))
|
self.assertIsNotNone(checkpoint_step(self.tmpdir, self.ticker, self.date, sig1))
|
||||||
# A different graph shape has no checkpoint to resume from.
|
# A different graph shape has no checkpoint to resume from.
|
||||||
self.assertFalse(has_checkpoint(self.tmpdir, self.ticker, self.date, sig2))
|
self.assertIsNone(checkpoint_step(self.tmpdir, self.ticker, self.date, sig2))
|
||||||
|
|
||||||
_should_crash = False
|
_should_crash = False
|
||||||
tid2 = thread_id(self.ticker, self.date, sig2)
|
tid2 = thread_id(self.ticker, self.date, sig2)
|
||||||
@@ -190,7 +189,7 @@ class TestCheckpointSignature(unittest.TestCase):
|
|||||||
result = graph.invoke({"count": 0}, config={"configurable": {"thread_id": tid2}})
|
result = graph.invoke({"count": 0}, config={"configurable": {"thread_id": tid2}})
|
||||||
self.assertEqual(result["count"], 11)
|
self.assertEqual(result["count"], 11)
|
||||||
# sig1's checkpoint remains untouched.
|
# sig1's checkpoint remains untouched.
|
||||||
self.assertTrue(has_checkpoint(self.tmpdir, self.ticker, self.date, sig1))
|
self.assertIsNotNone(checkpoint_step(self.tmpdir, self.ticker, self.date, sig1))
|
||||||
|
|
||||||
def test_run_signature_captures_graph_shape(self):
|
def test_run_signature_captures_graph_shape(self):
|
||||||
from tradingagents.graph.trading_graph import TradingAgentsGraph
|
from tradingagents.graph.trading_graph import TradingAgentsGraph
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import pytest
|
|||||||
from tradingagents.dataflows.symbol_utils import (
|
from tradingagents.dataflows.symbol_utils import (
|
||||||
NoMarketDataError,
|
NoMarketDataError,
|
||||||
crypto_base,
|
crypto_base,
|
||||||
is_yahoo_safe,
|
|
||||||
normalize_symbol,
|
normalize_symbol,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -88,17 +87,6 @@ class TestNoMarketDataError(unittest.TestCase):
|
|||||||
self.assertEqual(err.canonical, "FOOBAR")
|
self.assertEqual(err.canonical, "FOOBAR")
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.unit
|
|
||||||
class TestIsYahooSafe(unittest.TestCase):
|
|
||||||
def test_accepts_structural_chars(self):
|
|
||||||
for sym in ("AAPL", "GC=F", "^GSPC", "BRK.B", "BTC-USD"):
|
|
||||||
self.assertTrue(is_yahoo_safe(sym))
|
|
||||||
|
|
||||||
def test_rejects_slash_and_space(self):
|
|
||||||
for sym in ("a/b", "AA PL", ""):
|
|
||||||
self.assertFalse(is_yahoo_safe(sym))
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.unit
|
@pytest.mark.unit
|
||||||
class TestCryptoBase(unittest.TestCase):
|
class TestCryptoBase(unittest.TestCase):
|
||||||
def test_resolves_known_crypto_forms(self):
|
def test_resolves_known_crypto_forms(self):
|
||||||
|
|||||||
@@ -1,37 +1,9 @@
|
|||||||
import contextlib
|
from dotenv import find_dotenv, load_dotenv
|
||||||
import warnings
|
|
||||||
|
|
||||||
# Load .env files at package import so DEFAULT_CONFIG's env-var overlay
|
# Load .env at package import so DEFAULT_CONFIG's env-var overlay and every LLM
|
||||||
# (and every llm_clients consumer) sees the user's keys regardless of
|
# client see the user's keys whichever entry point started the process.
|
||||||
# which entry point started the process. find_dotenv(usecwd=True) walks
|
# usecwd=True walks from the working directory, so the installed console script
|
||||||
# from the CWD, so the installed `tradingagents` console script picks up
|
# finds the project's .env rather than looking beside site-packages. Values the
|
||||||
# the project's .env instead of stepping up from site-packages.
|
# caller has already exported are never overridden.
|
||||||
# load_dotenv defaults to override=False, so it never clobbers values
|
load_dotenv(find_dotenv(usecwd=True))
|
||||||
# the caller has already exported.
|
load_dotenv(find_dotenv(".env.enterprise", usecwd=True), override=False)
|
||||||
try:
|
|
||||||
from dotenv import find_dotenv, load_dotenv
|
|
||||||
|
|
||||||
load_dotenv(find_dotenv(usecwd=True))
|
|
||||||
load_dotenv(find_dotenv(".env.enterprise", usecwd=True), override=False)
|
|
||||||
except ImportError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# langchain-core 1.3.3 calls surface_langchain_deprecation_warnings() in
|
|
||||||
# its own __init__, which prepends default-action filters for its
|
|
||||||
# subclassed warning categories. To suppress a specific warning we must
|
|
||||||
# install our filter AFTER langchain-core has installed its own, so import
|
|
||||||
# it first. The package is a guaranteed transitive dep via langgraph.
|
|
||||||
with contextlib.suppress(ImportError):
|
|
||||||
import langchain_core # noqa: F401
|
|
||||||
|
|
||||||
# langgraph-checkpoint 4.0.3 calls Reviver() at module load without an
|
|
||||||
# explicit allowed_objects, which triggers a noisy pending-deprecation
|
|
||||||
# warning from langchain-core 1.3.3 on every interpreter start. The fix
|
|
||||||
# is already merged upstream (langchain-ai/langgraph#7743, 2026-05-08)
|
|
||||||
# and will arrive in the next langgraph-checkpoint release. Remove this
|
|
||||||
# block (and the langchain_core preload above) when we bump past it.
|
|
||||||
warnings.filterwarnings(
|
|
||||||
"ignore",
|
|
||||||
message=r"The default value of `allowed_objects`.*",
|
|
||||||
category=PendingDeprecationWarning,
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -71,9 +71,6 @@ _ALIASES = {
|
|||||||
"FRA40": "^FCHI", "EU50": "^STOXX50E", "HK50": "^HSI",
|
"FRA40": "^FCHI", "EU50": "^STOXX50E", "HK50": "^HSI",
|
||||||
}
|
}
|
||||||
|
|
||||||
# Yahoo symbols may contain letters, digits, and these structural characters.
|
|
||||||
_YAHOO_SAFE = re.compile(r"^[A-Za-z0-9._\-\^=]+$")
|
|
||||||
|
|
||||||
# HKEX codes as Yahoo spells them: the number zero-padded to 4 digits (#957).
|
# HKEX codes as Yahoo spells them: the number zero-padded to 4 digits (#957).
|
||||||
_HK_CODE = re.compile(r"^(\d{1,5})\.HK$")
|
_HK_CODE = re.compile(r"^(\d{1,5})\.HK$")
|
||||||
_SHANGHAI_SH = re.compile(r"^(\d{6})\.SH$")
|
_SHANGHAI_SH = re.compile(r"^(\d{6})\.SH$")
|
||||||
@@ -150,7 +147,3 @@ def normalize_symbol(raw: str) -> str:
|
|||||||
logger.info("Resolved symbol %r to Yahoo symbol %r", raw, canonical)
|
logger.info("Resolved symbol %r to Yahoo symbol %r", raw, canonical)
|
||||||
return canonical
|
return canonical
|
||||||
|
|
||||||
|
|
||||||
def is_yahoo_safe(symbol: str) -> bool:
|
|
||||||
"""True when ``symbol`` only contains characters Yahoo symbols use."""
|
|
||||||
return bool(symbol) and _YAHOO_SAFE.fullmatch(symbol) is not None
|
|
||||||
|
|||||||
@@ -70,7 +70,6 @@ def _apply_env_overrides(config: dict) -> dict:
|
|||||||
|
|
||||||
|
|
||||||
DEFAULT_CONFIG = _apply_env_overrides({
|
DEFAULT_CONFIG = _apply_env_overrides({
|
||||||
"project_dir": os.path.abspath(os.path.join(os.path.dirname(__file__), ".")),
|
|
||||||
"results_dir": os.getenv("TRADINGAGENTS_RESULTS_DIR") or os.path.join(_TRADINGAGENTS_HOME, "logs"),
|
"results_dir": os.getenv("TRADINGAGENTS_RESULTS_DIR") or os.path.join(_TRADINGAGENTS_HOME, "logs"),
|
||||||
"data_cache_dir": os.getenv("TRADINGAGENTS_CACHE_DIR") or os.path.join(_TRADINGAGENTS_HOME, "cache"),
|
"data_cache_dir": os.getenv("TRADINGAGENTS_CACHE_DIR") or os.path.join(_TRADINGAGENTS_HOME, "cache"),
|
||||||
"memory_log_path": os.getenv("TRADINGAGENTS_MEMORY_LOG_PATH") or os.path.join(_TRADINGAGENTS_HOME, "memory", "trading_memory.md"),
|
"memory_log_path": os.getenv("TRADINGAGENTS_MEMORY_LOG_PATH") or os.path.join(_TRADINGAGENTS_HOME, "memory", "trading_memory.md"),
|
||||||
|
|||||||
@@ -103,9 +103,6 @@ class AnalystWallTimeTracker:
|
|||||||
finished_at = monotonic() if completed_at is None else completed_at
|
finished_at = monotonic() if completed_at is None else completed_at
|
||||||
self._wall_times[analyst_key] = max(0.0, finished_at - started_at)
|
self._wall_times[analyst_key] = max(0.0, finished_at - started_at)
|
||||||
|
|
||||||
def get_wall_times(self) -> dict[str, float]:
|
|
||||||
return dict(self._wall_times)
|
|
||||||
|
|
||||||
def format_summary(self) -> str:
|
def format_summary(self) -> str:
|
||||||
parts = []
|
parts = []
|
||||||
for spec in self.plan.specs:
|
for spec in self.plan.specs:
|
||||||
|
|||||||
@@ -51,11 +51,6 @@ def get_checkpointer(data_dir: str | Path, ticker: str) -> Generator[SqliteSaver
|
|||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
|
|
||||||
def has_checkpoint(data_dir: str | Path, ticker: str, date: str, signature: str = "") -> bool:
|
|
||||||
"""Check whether a resumable checkpoint exists for ticker+date."""
|
|
||||||
return checkpoint_step(data_dir, ticker, date, signature) is not None
|
|
||||||
|
|
||||||
|
|
||||||
def checkpoint_step(data_dir: str | Path, ticker: str, date: str, signature: str = "") -> int | None:
|
def checkpoint_step(data_dir: str | Path, ticker: str, date: str, signature: str = "") -> int | None:
|
||||||
"""Return the step number of the latest checkpoint, or None if none exists."""
|
"""Return the step number of the latest checkpoint, or None if none exists."""
|
||||||
db = _db_path(data_dir, ticker)
|
db = _db_path(data_dir, ticker)
|
||||||
|
|||||||
@@ -145,9 +145,6 @@ class TradingAgentsGraph:
|
|||||||
)
|
)
|
||||||
self.reflector = Reflector(self.quick_thinking_llm)
|
self.reflector = Reflector(self.quick_thinking_llm)
|
||||||
|
|
||||||
# State tracking
|
|
||||||
self.curr_state = None
|
|
||||||
|
|
||||||
# Graph-shape-affecting run choices, kept for the checkpoint signature.
|
# Graph-shape-affecting run choices, kept for the checkpoint signature.
|
||||||
self.selected_analysts = tuple(selected_analysts)
|
self.selected_analysts = tuple(selected_analysts)
|
||||||
|
|
||||||
@@ -538,9 +535,6 @@ class TradingAgentsGraph:
|
|||||||
else:
|
else:
|
||||||
final_state = self.graph.invoke(graph_input, **args)
|
final_state = self.graph.invoke(graph_input, **args)
|
||||||
|
|
||||||
# Store current state for reflection.
|
|
||||||
self.curr_state = final_state
|
|
||||||
|
|
||||||
# Log state to disk.
|
# Log state to disk.
|
||||||
self._log_state(trade_date, final_state)
|
self._log_state(trade_date, final_state)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user