diff --git a/tests/test_fundamentals_units.py b/tests/test_fundamentals_units.py new file mode 100644 index 000000000..f960ad6c6 --- /dev/null +++ b/tests/test_fundamentals_units.py @@ -0,0 +1,39 @@ +"""Yahoo's percent-valued fields say they are percentages (#1414). + +``Ticker.info`` gives ``dividendYield`` and ``debtToEquity`` in percent (0.41 is +0.41%; 78.4 is 78.4%, a ratio of 0.78) but margins and returns as fractions +(0.27 is 27%). Printed side by side without a unit, one scale reads as the other. +""" + +from unittest import mock + +import pytest + +from tradingagents.dataflows import date_window +from tradingagents.dataflows.vendors.yahoo import fundamentals + +TODAY = "2026-09-26" + + +def _fundamentals(info): + with mock.patch.object(date_window, "get_current_date", return_value=TODAY), \ + mock.patch.object(fundamentals, "yf_retry", lambda fn: info): + return fundamentals.get_fundamentals("AAPL", TODAY) + + +@pytest.mark.unit +def test_percent_fields_carry_their_unit_and_fractions_are_unchanged(): + out = _fundamentals({"longName": "Apple Inc.", "dividendYield": 0.32, "debtToEquity": 78.445, + "profitMargins": 0.27619, "returnOnEquity": 1.4875101}) + + assert "Dividend Yield: 0.32%" in out + assert "Debt to Equity: 78.445% (0.78x)" in out + assert "Profit Margin: 0.27619" in out + assert "Return on Equity: 1.4875101" in out + + +@pytest.mark.unit +def test_an_absent_percent_field_is_left_out(): + out = _fundamentals({"longName": "JPMorgan Chase & Co.", "profitMargins": 0.35}) + + assert "Dividend Yield" not in out and "Debt to Equity" not in out diff --git a/tradingagents/dataflows/vendors/yahoo/fundamentals.py b/tradingagents/dataflows/vendors/yahoo/fundamentals.py index 98e3dacc8..15a6b7b97 100644 --- a/tradingagents/dataflows/vendors/yahoo/fundamentals.py +++ b/tradingagents/dataflows/vendors/yahoo/fundamentals.py @@ -36,6 +36,10 @@ def get_fundamentals( if not info: raise_for_empty(ticker, canonical, "fundamentals") + # Yahoo gives these two in percent (dividendYield 0.41 is 0.41%; debtToEquity + # 78.4 is 78.4%, a ratio of 0.78) but the margins and returns as fractions, + # so each carries its unit. + dividend_yield, debt_to_equity = info.get("dividendYield"), info.get("debtToEquity") fields = [ ("Name", info.get("longName")), ("Sector", info.get("sector")), @@ -47,7 +51,7 @@ def get_fundamentals( ("Price to Book", info.get("priceToBook")), ("EPS (TTM)", info.get("trailingEps")), ("Forward EPS", info.get("forwardEps")), - ("Dividend Yield", info.get("dividendYield")), + ("Dividend Yield", None if dividend_yield is None else f"{dividend_yield}%"), ("Beta", info.get("beta")), ("52 Week High", info.get("fiftyTwoWeekHigh")), ("52 Week Low", info.get("fiftyTwoWeekLow")), @@ -61,7 +65,8 @@ def get_fundamentals( ("Operating Margin", info.get("operatingMargins")), ("Return on Equity", info.get("returnOnEquity")), ("Return on Assets", info.get("returnOnAssets")), - ("Debt to Equity", info.get("debtToEquity")), + ("Debt to Equity", None if debt_to_equity is None + else f"{debt_to_equity}% ({debt_to_equity / 100:.2f}x)"), ("Current Ratio", info.get("currentRatio")), ("Book Value", info.get("bookValue")), ("Free Cash Flow", info.get("freeCashflow")),