From 04b691804c2bbff3b89f68fd06e25b9567e59aa4 Mon Sep 17 00:00:00 2001 From: Yijia-Xiao Date: Thu, 17 Sep 2026 23:37:43 +0000 Subject: [PATCH] fix(dataflows): include the analysis day in the Alpha Vantage news window - time_to was midnight starting the end date, dropping that day's news --- tests/test_alpha_vantage_hardening.py | 17 +++++++++++++++++ tradingagents/dataflows/alpha_vantage_common.py | 11 ++++++++--- tradingagents/dataflows/alpha_vantage_news.py | 4 ++-- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/tests/test_alpha_vantage_hardening.py b/tests/test_alpha_vantage_hardening.py index 6235241e6..832fa4c51 100644 --- a/tests/test_alpha_vantage_hardening.py +++ b/tests/test_alpha_vantage_hardening.py @@ -166,3 +166,20 @@ def test_global_news_omitted_optionals_use_the_configured_defaults(monkeypatch): alpha_vantage_news.get_global_news("2026-08-14", None, None) assert seen["time_from"].startswith("20260811") and seen["limit"] == "9" + + +@pytest.mark.unit +def test_the_news_window_includes_the_analysis_day(monkeypatch): + """time_to was midnight at the start of the end date, so everything + published during the analysis day, the most decision-relevant day, was + excluded. The yfinance path includes it.""" + from tradingagents.dataflows import alpha_vantage_news + + seen = {} + monkeypatch.setattr(alpha_vantage_news, "_make_api_request", + lambda fn, params: seen.update(params) or "{}") + + alpha_vantage_news.get_news("AAPL", "2026-03-10", "2026-03-14") + + assert seen["time_from"] == "20260310T0000" + assert seen["time_to"] == "20260314T2359" diff --git a/tradingagents/dataflows/alpha_vantage_common.py b/tradingagents/dataflows/alpha_vantage_common.py index 95dda491d..7f07af9b1 100644 --- a/tradingagents/dataflows/alpha_vantage_common.py +++ b/tradingagents/dataflows/alpha_vantage_common.py @@ -34,8 +34,13 @@ def get_api_key() -> str: ) return api_key -def format_datetime_for_api(date_input) -> str: - """Convert various date formats to YYYYMMDDTHHMM format required by Alpha Vantage API.""" +def format_datetime_for_api(date_input, end_of_day: bool = False) -> str: + """Convert various date formats to the YYYYMMDDTHHMM Alpha Vantage expects. + + A plain date means midnight, which is the start of that day. For the end of + a window pass ``end_of_day`` so the day itself is inside it, rather than + dropping everything published on the analysis date. + """ if isinstance(date_input, str): # If already in correct format, return as-is if len(date_input) == 13 and 'T' in date_input: @@ -43,7 +48,7 @@ def format_datetime_for_api(date_input) -> str: # Try to parse common date formats try: dt = datetime.strptime(date_input, "%Y-%m-%d") - return dt.strftime("%Y%m%dT0000") + return dt.strftime("%Y%m%dT2359" if end_of_day else "%Y%m%dT0000") except ValueError: try: dt = datetime.strptime(date_input, "%Y-%m-%d %H:%M") diff --git a/tradingagents/dataflows/alpha_vantage_news.py b/tradingagents/dataflows/alpha_vantage_news.py index 4431eadc1..787de8018 100644 --- a/tradingagents/dataflows/alpha_vantage_news.py +++ b/tradingagents/dataflows/alpha_vantage_news.py @@ -21,7 +21,7 @@ def get_news(ticker, start_date, end_date) -> dict[str, str] | str: params = { "tickers": ticker, "time_from": format_datetime_for_api(start_date), - "time_to": format_datetime_for_api(end_date), + "time_to": format_datetime_for_api(end_date, end_of_day=True), } return _make_api_request("NEWS_SENTIMENT", params) @@ -56,7 +56,7 @@ def get_global_news(curr_date, look_back_days: int | None = None, limit: int | N params = { "topics": "financial_markets,economy_macro,economy_monetary", "time_from": format_datetime_for_api(start_date), - "time_to": format_datetime_for_api(curr_date), + "time_to": format_datetime_for_api(curr_date, end_of_day=True), "limit": str(limit), }