mirror of
https://github.com/TauricResearch/TradingAgents.git
synced 2026-09-27 23:12:39 +03:00
refactor: name the data layer's date argument as_of_date
- vendor functions and date_window take as_of_date, the date data is served as of; the model-facing tool arguments are unchanged - build_instrument_context and resolve_instrument_context take trade_date, which is what they receive
This commit is contained in:
@@ -82,7 +82,7 @@ def test_fundamentals_look_ahead_filter_runs_on_json_string(monkeypatch):
|
||||
# #1115: the payload arrives as a JSON *string*; the old dict-only guard let
|
||||
# future-dated fiscal periods leak into historical runs.
|
||||
monkeypatch.setattr(avf, "_make_api_request", lambda fn, params: _FUNDAMENTALS_JSON)
|
||||
out = avf.get_balance_sheet("AAPL", curr_date="2024-01-01")
|
||||
out = avf.get_balance_sheet("AAPL", as_of_date="2024-01-01")
|
||||
assert isinstance(out, str) # callers still receive a str
|
||||
parsed = json.loads(out)
|
||||
assert [r["fiscalDateEnding"] for r in parsed["annualReports"]] == ["2023-12-31"]
|
||||
@@ -98,7 +98,7 @@ def test_fundamentals_no_curr_date_passes_through(monkeypatch):
|
||||
@pytest.mark.unit
|
||||
def test_fundamentals_non_json_body_unchanged(monkeypatch):
|
||||
monkeypatch.setattr(avf, "_make_api_request", lambda fn, params: "not-json")
|
||||
assert avf.get_cashflow("AAPL", curr_date="2024-01-01") == "not-json"
|
||||
assert avf.get_cashflow("AAPL", as_of_date="2024-01-01") == "not-json"
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
+6
-6
@@ -141,7 +141,7 @@ class FredFormattingTests(unittest.TestCase):
|
||||
self.assertEqual(len(body_rows), fred.MAX_ROWS)
|
||||
|
||||
def test_window_is_lookahead_safe(self):
|
||||
# observation_end must equal curr_date so a past date never pulls future data.
|
||||
# observation_end must equal as_of_date so a past date never pulls future data.
|
||||
captured = {}
|
||||
|
||||
def _capture(path, params):
|
||||
@@ -156,9 +156,9 @@ class FredFormattingTests(unittest.TestCase):
|
||||
|
||||
def test_requests_pin_the_data_vintage(self):
|
||||
# #1275: both the metadata and observations requests must pin the vintage
|
||||
# to curr_date (clamped to FRED's today), or FRED serves the latest
|
||||
# to as_of_date (clamped to FRED's today), or FRED serves the latest
|
||||
# revision and revision-prone series leak future information. A past
|
||||
# curr_date sits below FRED's today, so it pins through unchanged.
|
||||
# as_of_date sits below FRED's today, so it pins through unchanged.
|
||||
captured = {}
|
||||
|
||||
def _capture(path, params):
|
||||
@@ -174,11 +174,11 @@ class FredFormattingTests(unittest.TestCase):
|
||||
self.assertEqual(captured[path]["realtime_end"], "2025-09-30", path)
|
||||
|
||||
def test_future_curr_date_clamps_vintage_to_fred_today(self):
|
||||
# #1275 regression: on a live run curr_date is the caller's LOCAL date,
|
||||
# #1275 regression: on a live run as_of_date is the caller's LOCAL date,
|
||||
# which can be a day ahead of FRED's US-Central clock. Pinning the vintage
|
||||
# to that future date 400s, and the routing layer then drops macro data
|
||||
# silently. The pin must clamp to FRED's today; the observation window
|
||||
# (future bars can't exist yet) stays at curr_date.
|
||||
# (future bars can't exist yet) stays at as_of_date.
|
||||
captured = {}
|
||||
|
||||
def _capture(path, params):
|
||||
@@ -192,7 +192,7 @@ class FredFormattingTests(unittest.TestCase):
|
||||
for path in ("series", "series/observations"):
|
||||
self.assertEqual(captured[path]["realtime_start"], "2026-08-31", path)
|
||||
self.assertEqual(captured[path]["realtime_end"], "2026-08-31", path)
|
||||
# the observation window still tracks curr_date, not the clamped vintage
|
||||
# the observation window still tracks as_of_date, not the clamped vintage
|
||||
self.assertEqual(captured["series/observations"]["observation_end"], "2026-09-01")
|
||||
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ FRED (#1275), social (#1220) and memory (#1251) leaks.
|
||||
|
||||
Both vendors withhold on one shared rule (``date_window.withhold_live_profile``)
|
||||
so switching ``fundamental_data`` between them cannot reintroduce the leak. The
|
||||
statement tools stay point-in-time by filtering on ``curr_date``, and a live run
|
||||
statement tools stay point-in-time by filtering on ``as_of_date``, and a live run
|
||||
is unchanged. All API access is mocked.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
@@ -45,19 +45,19 @@ _LEAKY = ("3500000000000", "34.2", "260.1", "391000000000",
|
||||
"Apple Inc.", "Technology", "Consumer Electronics")
|
||||
|
||||
|
||||
def _yf(curr_date, info=_INFO, today=_TODAY):
|
||||
def _yf(as_of_date, info=_INFO, today=_TODAY):
|
||||
with mock.patch.object(date_window, "get_current_date", return_value=today), \
|
||||
mock.patch.object(yahoo_fundamentals, "yf_retry", lambda fn: info), \
|
||||
mock.patch.object(yahoo_market.yf, "Ticker"):
|
||||
return yahoo_fundamentals.get_fundamentals("AAPL", curr_date)
|
||||
return yahoo_fundamentals.get_fundamentals("AAPL", as_of_date)
|
||||
|
||||
|
||||
def _av(curr_date, today=_TODAY):
|
||||
def _av(as_of_date, today=_TODAY):
|
||||
"""Alpha Vantage path; the API call is mocked so a leak would be visible."""
|
||||
with mock.patch.object(date_window, "get_current_date", return_value=today), \
|
||||
mock.patch.object(av, "_make_api_request",
|
||||
return_value="MarketCapitalization: 3500000000000") as req:
|
||||
return av.get_fundamentals("AAPL", curr_date), req
|
||||
return av.get_fundamentals("AAPL", as_of_date), req
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
|
||||
@@ -102,4 +102,4 @@ def test_an_unreachable_yahoo_is_not_reported_as_a_symbol_without_insider_data()
|
||||
with mock.patch.object(fundamentals.yf, "Ticker", return_value=ticker), \
|
||||
mock.patch.object(fundamentals, "vendor_reachable", return_value=False), \
|
||||
pytest.raises(VendorRateLimitError):
|
||||
fundamentals.get_insider_transactions("AAPL", curr_date="2026-09-21")
|
||||
fundamentals.get_insider_transactions("AAPL", as_of_date="2026-09-21")
|
||||
|
||||
@@ -70,14 +70,14 @@ def test_alpha_vantage_insider_filings_after_the_date_are_dropped():
|
||||
@pytest.mark.unit
|
||||
def test_polymarket_withholds_live_odds_from_a_historical_run():
|
||||
with mock.patch.object(polymarket, "_request", side_effect=AssertionError("must not fetch")):
|
||||
out = polymarket.get_prediction_markets("Fed rate cut", curr_date="2025-06-01")
|
||||
out = polymarket.get_prediction_markets("Fed rate cut", as_of_date="2025-06-01")
|
||||
assert "withheld" in out
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_polymarket_serves_a_current_run():
|
||||
with mock.patch.object(polymarket, "_request", return_value={"events": []}) as req:
|
||||
polymarket.get_prediction_markets("Fed rate cut", curr_date=polymarket.get_current_date())
|
||||
polymarket.get_prediction_markets("Fed rate cut", as_of_date=polymarket.get_current_date())
|
||||
req.assert_called_once()
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ def test_a_historical_run_is_told_the_identity_is_current(monkeypatch):
|
||||
identity = {"company_name": "Example Corp", "sector": "Technology",
|
||||
"industry": "Software", "exchange": "NMS"}
|
||||
|
||||
historical = build_instrument_context("EXMP", "stock", identity, curr_date="2024-03-14")
|
||||
historical = build_instrument_context("EXMP", "stock", identity, trade_date="2024-03-14")
|
||||
assert "Example Corp" in historical
|
||||
assert "2024-03-14" in historical and "today" in historical.lower()
|
||||
|
||||
@@ -114,7 +114,7 @@ def test_a_current_run_is_not_cluttered_with_a_vintage_note(monkeypatch):
|
||||
from tradingagents.dataflows.date_window import get_current_date
|
||||
|
||||
today = build_instrument_context("EXMP", "stock", {"company_name": "Example Corp"},
|
||||
curr_date=get_current_date())
|
||||
trade_date=get_current_date())
|
||||
assert "Example Corp" in today
|
||||
assert "resolved today" not in today.lower()
|
||||
|
||||
@@ -297,7 +297,7 @@ def test_an_unavailable_notice_names_no_date_after_the_run():
|
||||
coverage_gap([pd.Timestamp(today, tz="UTC")], "2025-01-01", "2025-01-07", "Feed", "news"),
|
||||
withhold_live_profile("2025-01-07", "AAPL"),
|
||||
_yf_insider(_insider_frame(today), "2025-01-07"),
|
||||
build_instrument_context("EXMP", "stock", {"company_name": "Example"}, curr_date="2025-01-07"),
|
||||
build_instrument_context("EXMP", "stock", {"company_name": "Example"}, trade_date="2025-01-07"),
|
||||
]
|
||||
for notice in notices:
|
||||
assert _dates_after(notice, "2025-01-07") == [], notice
|
||||
|
||||
Reference in New Issue
Block a user