feat: make reports root directory configurable via env var

TRADINGAGENTS_REPORTS_DIR now controls where all reports land (scans,
analysis, portfolio artifacts). Both report_paths.REPORTS_ROOT and
ReportStore.data_dir read from the same env var so the entire
reports/daily/{date}/... tree is rooted at one configurable location.

PORTFOLIO_DATA_DIR still works as a portfolio-specific override.
Falls back to "reports" (relative to CWD) when neither is set.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Ahmet Guzererler 2026-03-24 00:15:04 +01:00
parent 0951ef17ec
commit 56c5bea1ae
3 changed files with 13 additions and 5 deletions

View File

@ -78,8 +78,11 @@ FINNHUB_API_KEY=
# PostgreSQL connection string for Supabase (required for portfolio commands)
# SUPABASE_CONNECTION_STRING=postgresql://postgres.<project>:<password>@aws-1-<region>.pooler.supabase.com:6543/postgres
# Portfolio data directory (where JSON reports are stored)
# TRADINGAGENTS_PORTFOLIO_DATA_DIR=reports
# Root directory for all reports (scans, analysis, portfolio artifacts).
# All output lands under {REPORTS_DIR}/daily/{date}/...
# PORTFOLIO_DATA_DIR overrides this for portfolio-only reports if you need them split.
# TRADINGAGENTS_REPORTS_DIR=/absolute/path/to/reports
# PORTFOLIO_DATA_DIR=/absolute/path/to/reports
# Portfolio constraint overrides
# TRADINGAGENTS_PM_MAX_POSITIONS=15 # maximum number of open positions

View File

@ -29,7 +29,9 @@ from tradingagents.default_config import _env, _env_float, _env_int
PORTFOLIO_CONFIG: dict = {
"supabase_connection_string": os.getenv("SUPABASE_CONNECTION_STRING", ""),
"data_dir": _env("PORTFOLIO_DATA_DIR", "reports"),
# PORTFOLIO_DATA_DIR takes precedence; falls back to TRADINGAGENTS_REPORTS_DIR,
# then to "reports" (relative to CWD) — same default as report_paths.REPORTS_ROOT.
"data_dir": os.getenv("PORTFOLIO_DATA_DIR") or _env("REPORTS_DIR", "reports"),
"max_positions": 15,
"max_position_pct": 0.15,
"max_sector_pct": 0.35,
@ -46,7 +48,7 @@ def get_portfolio_config() -> dict:
"""
cfg = dict(PORTFOLIO_CONFIG)
cfg["supabase_connection_string"] = os.getenv("SUPABASE_CONNECTION_STRING", cfg["supabase_connection_string"])
cfg["data_dir"] = _env("PORTFOLIO_DATA_DIR", cfg["data_dir"])
cfg["data_dir"] = os.getenv("PORTFOLIO_DATA_DIR") or _env("REPORTS_DIR", cfg["data_dir"])
cfg["max_positions"] = _env_int("PM_MAX_POSITIONS", cfg["max_positions"])
cfg["max_position_pct"] = _env_float("PM_MAX_POSITION_PCT", cfg["max_position_pct"])
cfg["max_sector_pct"] = _env_float("PM_MAX_SECTOR_PCT", cfg["max_sector_pct"])

View File

@ -19,9 +19,12 @@ all generated artifacts land under a single ``reports/`` tree::
from __future__ import annotations
import os
from pathlib import Path
REPORTS_ROOT = Path("reports")
# Configurable via TRADINGAGENTS_REPORTS_DIR env var.
# Falls back to "reports" (relative to CWD) when unset.
REPORTS_ROOT = Path(os.getenv("TRADINGAGENTS_REPORTS_DIR") or "reports")
def get_daily_dir(date: str) -> Path: