mirror of
https://github.com/TauricResearch/TradingAgents.git
synced 2026-11-03 16:12:44 +02:00
- settlement enters at the first session after the decision date, so news published after that day's close is not scored against the same day's close
87 lines
3.0 KiB
Python
87 lines
3.0 KiB
Python
"""Symbol normalization must apply on every yfinance path, not just price fetch.
|
|
|
|
Regression tests for #983 (instrument identity), #984 (reflection returns), and
|
|
the news path: a broker symbol like XAUUSD must resolve to the same Yahoo symbol
|
|
(GC=F) that the price path uses, so identity, realized-return, and news lookups
|
|
hit the right instrument instead of failing/mismatching.
|
|
"""
|
|
import pandas as pd
|
|
|
|
import tradingagents.agents.context as au
|
|
import tradingagents.dataflows.vendors.yahoo.market as yahoo_market
|
|
import tradingagents.dataflows.vendors.yahoo.news as ynews
|
|
from tradingagents.memory import settlement
|
|
|
|
|
|
def test_identity_lookup_normalizes_symbol(monkeypatch):
|
|
seen = {}
|
|
|
|
class FakeTicker:
|
|
def __init__(self, symbol):
|
|
seen["symbol"] = symbol
|
|
|
|
@property
|
|
def info(self):
|
|
return {"longName": "Gold Futures", "quoteType": "FUTURE"}
|
|
|
|
monkeypatch.setattr(yahoo_market.yf, "Ticker", FakeTicker)
|
|
au._identity.cache_clear()
|
|
|
|
identity = au.resolve_instrument_identity("XAUUSD")
|
|
|
|
assert seen["symbol"] == "GC=F" # normalized, not the raw broker symbol
|
|
assert identity.get("company_name") == "Gold Futures"
|
|
|
|
|
|
def test_fetch_returns_normalizes_symbol(monkeypatch):
|
|
queried = []
|
|
|
|
class FakeTicker:
|
|
def __init__(self, symbol):
|
|
queried.append(symbol)
|
|
|
|
def history(self, *args, **kwargs):
|
|
prices = [100.0, 101.0, 102.0, 103.0, 104.0, 105.0, 106.0]
|
|
idx = pd.date_range(start="2025-01-02", periods=len(prices), freq="D")
|
|
return pd.DataFrame({"Close": prices}, index=idx)
|
|
|
|
monkeypatch.setattr(yahoo_market.yf, "Ticker", FakeTicker)
|
|
|
|
raw, alpha, days, resolved = settlement.fetch_returns(
|
|
"XAUUSD", "2025-01-02", holding_days=5, benchmark="SPY"
|
|
)
|
|
|
|
assert queried[0] == "GC=F" # stock symbol normalized (#984)
|
|
assert queried[1] == "SPY" # benchmark left as the canonical symbol
|
|
assert raw is not None and days is not None
|
|
assert resolved == "2025-01-08" # resolution date recorded (#1251)
|
|
|
|
|
|
def test_news_lookup_normalizes_symbol(monkeypatch):
|
|
seen = {}
|
|
|
|
class FakeTicker:
|
|
def __init__(self, symbol):
|
|
seen["symbol"] = symbol
|
|
|
|
def get_news(self, count):
|
|
return []
|
|
|
|
class FakeSearch:
|
|
def __init__(self, query, **k):
|
|
seen["searched"] = query
|
|
self.news = [{"title": "Gold", "publisher": "P", "link": "l",
|
|
"providerPublishTime": 1736150400, "relatedTickers": ["GC=F"]}]
|
|
self.quotes = [{"symbol": "GC=F"}]
|
|
|
|
monkeypatch.setattr(ynews.yf, "Ticker", FakeTicker)
|
|
monkeypatch.setattr(ynews.yf, "Search", FakeSearch)
|
|
monkeypatch.setattr(ynews, "yf_retry", lambda fn: fn())
|
|
|
|
out = ynews.get_news_yfinance("XAUUSD", "2025-01-01", "2025-01-10")
|
|
|
|
assert seen["symbol"] == "GC=F" # news queried with the canonical symbol
|
|
assert seen["searched"] == "GC=F"
|
|
assert "XAUUSD" in out # the user's ticker stays in the report
|
|
assert "GC=F" in out # provenance noted
|