mirror of
https://github.com/TauricResearch/TradingAgents.git
synced 2026-11-03 16:12:44 +02:00
refactor(cli): save a run's reports through the graph, as a script does
- TradingAgentsGraph.default_report_path names the results_dir/reports/TICKER_stamp folder; save_reports and the CLI both use it
This commit is contained in:
+4
-9
@@ -1,6 +1,5 @@
|
||||
"""Running one analysis from the CLI: build the graph, stream it into the live view, save the report."""
|
||||
|
||||
import datetime
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
@@ -31,7 +30,6 @@ from tradingagents.graph.analyst_execution import (
|
||||
build_analyst_execution_plan,
|
||||
)
|
||||
from tradingagents.graph.trading_graph import TradingAgentsGraph
|
||||
from tradingagents.reporting import write_report_tree
|
||||
|
||||
|
||||
def _run_directory(config: dict, ticker: str, trade_date: str) -> Path:
|
||||
@@ -384,29 +382,26 @@ def run_analysis(checkpoint: bool | None = None, portfolio=None, flags=None):
|
||||
)
|
||||
console.print(f"[dim]{analyst_wall_time_tracker.format_summary()}[/dim]")
|
||||
|
||||
_offer_reports(final_state, graph, config, selections["ticker"],
|
||||
_offer_reports(final_state, graph, selections["ticker"],
|
||||
save=flags.get("save"), show=flags.get("show"))
|
||||
|
||||
|
||||
def _offer_reports(final_state, graph, config, ticker, save=None, show=None):
|
||||
def _offer_reports(final_state, graph, ticker, save=None, show=None):
|
||||
"""Save the report tree and show it; ``save``/``show`` answer the questions when given."""
|
||||
asked = save is None
|
||||
if asked:
|
||||
save = typer.prompt("Save report?", default="Y").strip().upper() in ("Y", "YES", "")
|
||||
if save:
|
||||
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
# Under results_dir, not the working directory: in Docker the working
|
||||
# directory is inside the container and the report goes with it, while
|
||||
# results_dir is the mounted volume the rest of the run already writes to.
|
||||
save_path = (Path(config["results_dir"]) / "reports"
|
||||
/ f"{safe_ticker_component(ticker)}_{timestamp}")
|
||||
save_path = graph.default_report_path(ticker)
|
||||
if asked: # someone at the prompt may pick another folder
|
||||
save_path = Path(typer.prompt(
|
||||
"Save path (press Enter for default)", default=str(save_path)
|
||||
).strip())
|
||||
try:
|
||||
report_file = write_report_tree(final_state, ticker, save_path,
|
||||
settings=graph.run_settings())
|
||||
report_file = graph.save_reports(final_state, ticker, save_path)
|
||||
console.print(f"\n[green]✓ Report saved to:[/green] {save_path.resolve()}")
|
||||
console.print(f" [dim]Complete report:[/dim] {report_file.name}")
|
||||
except Exception as e:
|
||||
|
||||
@@ -95,10 +95,14 @@ def test_save_and_show_answer_the_questions_after_the_run(monkeypatch, tmp_path)
|
||||
monkeypatch.setattr(run.typer, "prompt", no_prompt)
|
||||
shown = []
|
||||
monkeypatch.setattr(run, "display_complete_report", lambda state: shown.append(state))
|
||||
graph = type("G", (), {"run_settings": lambda self: {}})()
|
||||
from tradingagents.graph.trading_graph import TradingAgentsGraph
|
||||
|
||||
graph = object.__new__(TradingAgentsGraph)
|
||||
graph.config = {"results_dir": str(tmp_path)}
|
||||
graph.run_settings = lambda: {}
|
||||
state = {"market_report": "M", "final_trade_decision": "**Rating**: Hold"}
|
||||
|
||||
run._offer_reports(state, graph, {"results_dir": str(tmp_path)}, "NVDA", save=True, show=False)
|
||||
run._offer_reports(state, graph, "NVDA", save=True, show=False)
|
||||
|
||||
assert list(tmp_path.glob("reports/NVDA_*/complete_report.md"))
|
||||
assert shown == []
|
||||
|
||||
@@ -50,8 +50,10 @@ def test_save_reports_explicit_path(tmp_path):
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_save_reports_defaults_under_results_dir(tmp_path):
|
||||
mock_self = SimpleNamespace(config={"results_dir": str(tmp_path)}, run_settings=lambda: SETTINGS)
|
||||
out = TradingAgentsGraph.save_reports(mock_self, _state(), "AAPL")
|
||||
graph = object.__new__(TradingAgentsGraph)
|
||||
graph.config = {"results_dir": str(tmp_path)}
|
||||
graph.run_settings = lambda: SETTINGS
|
||||
out = graph.save_reports(_state(), "AAPL")
|
||||
assert out.exists()
|
||||
assert out.parent.parent.name == "reports" # results_dir/reports/AAPL_<stamp>/...
|
||||
assert out.parent.name.startswith("AAPL_")
|
||||
|
||||
@@ -294,14 +294,14 @@ class TradingAgentsGraph:
|
||||
an explicit ``save_path`` or let it default under ``results_dir``.
|
||||
"""
|
||||
if save_path is None:
|
||||
stamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
save_path = (
|
||||
Path(self.config["results_dir"])
|
||||
/ "reports"
|
||||
/ f"{safe_ticker_component(ticker)}_{stamp}"
|
||||
)
|
||||
save_path = self.default_report_path(ticker)
|
||||
return write_report_tree(final_state, ticker, save_path, settings=self.run_settings())
|
||||
|
||||
def default_report_path(self, ticker) -> Path:
|
||||
"""Where a run's reports go unless told otherwise: under results_dir, stamped now."""
|
||||
stamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
return Path(self.config["results_dir"]) / "reports" / f"{safe_ticker_component(ticker)}_{stamp}"
|
||||
|
||||
def create_run_state(self, company_name, trade_date, asset_type: str = "stock", portfolio=None):
|
||||
"""Build a run's initial state; propagate() and the CLI both start here.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user